From 94f9383db79fd2104263d31b37607a4729c63fe2 Mon Sep 17 00:00:00 2001 From: metersphere-bot <78466014+metersphere-bot@users.noreply.github.com> Date: Thu, 2 Sep 2021 16:31:30 +0800 Subject: [PATCH] =?UTF-8?q?feat=20(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=90=88=E5=B9=B6=E6=8F=92=E4=BB=B6=E9=9C=80?= =?UTF-8?q?=E6=B1=82=E4=BB=A3=E7=A0=81=20(#5911)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat (接口自动化): 动态插件初步完整版 (#5467) * feat (接口自动化): 合并插件需求代码 Co-authored-by: fit2-zhao Co-authored-by: fit2-zhao <70558837+fit2-zhao@users.noreply.github.com> --- backend/pom.xml | 7 + .../automation/SaveApiScenarioRequest.java | 2 +- .../automation/parse/HarScenarioParser.java | 2 +- .../dto/automation/parse/MsJmeterParser.java | 2 +- .../automation/parse/MsScenarioParser.java | 2 +- .../parse/PostmanScenarioParser.java | 2 +- .../dto/definition/RunDefinitionRequest.java | 2 +- .../definition/SaveApiDefinitionRequest.java | 2 +- .../definition/SaveApiTestCaseRequest.java | 2 +- .../parse/JmeterDefinitionParser.java | 2 +- .../{MsTestElement.java => ElementUtil.java} | 207 ++-- .../dto/definition/request/MsScenario.java | 14 +- .../dto/definition/request/MsTestPlan.java | 7 +- .../dto/definition/request/MsThreadGroup.java | 7 +- .../definition/request/OldVersionUtil.java | 1 + .../definition/request/ParameterConfig.java | 3 +- .../request/assertions/MsAssertions.java | 8 +- .../request/auth/MsAuthManager.java | 8 +- .../configurations/MsHeaderManager.java | 8 +- .../request/controller/MsIfController.java | 8 +- .../request/controller/MsLoopController.java | 16 +- .../controller/MsTransactionController.java | 12 +- .../request/dns/MsDNSCacheManager.java | 7 +- .../definition/request/extract/MsExtract.java | 8 +- .../request/processors/MsJSR223Processor.java | 12 +- .../processors/post/MsJDBCPostProcessor.java | 23 +- .../post/MsJSR223PostProcessor.java | 7 +- .../processors/pre/MsJDBCPreProcessor.java | 23 +- .../processors/pre/MsJSR223PreProcessor.java | 7 +- .../request/sampler/MsDebugSampler.java | 8 +- .../request/sampler/MsDubboSampler.java | 24 +- .../request/sampler/MsHTTPSamplerProxy.java | 35 +- .../request/sampler/MsJDBCSampler.java | 24 +- .../request/sampler/MsTCPSampler.java | 27 +- .../request/timer/MsConstantTimer.java | 8 +- .../request/unknown/MsJmeterElement.java | 8 +- .../api/parse/HarScenarioAbstractParser.java | 2 +- .../parse/PostmanAbstractParserParser.java | 2 +- .../api/parse/old/PostmanParser.java | 2 +- .../api/parse/old/Swagger2Parser.java | 2 +- .../api/service/ApiAutomationService.java | 16 +- .../api/service/ApiTestCaseService.java | 12 +- .../api/service/EsbApiParamService.java | 2 +- .../service/HistoricalDataUpgradeService.java | 2 +- .../api/service/TcpApiParamService.java | 2 +- .../io/metersphere/base/domain/Plugin.java | 30 + .../base/domain/PluginExample.java | 880 ++++++++++++++++++ .../base/domain/PluginWithBLOBs.java | 18 + .../metersphere/base/mapper/PluginMapper.java | 37 + .../metersphere/base/mapper/PluginMapper.xml | 375 ++++++++ .../metersphere/commons/utils/FileUtils.java | 25 +- .../io/metersphere/commons/utils/LogUtil.java | 1 + .../metersphere/commons/utils/ShiroUtils.java | 2 + .../controller/PluginController.java | 48 + .../controller/request/PluginRequest.java | 9 + .../controller/request/PluginResourceDTO.java | 9 + .../listener/AppStartListener.java | 6 +- .../io/metersphere/service/PluginService.java | 197 ++++ .../metersphere/service/utils/CommonUtil.java | 93 ++ .../track/service/TestPlanApiCaseService.java | 5 +- .../track/service/TestPlanService.java | 3 + .../db/migration/V95__v1.13_release.sql | 17 + frontend/package.json | 7 +- .../api/automation/api-automation.js | 10 +- .../api/automation/scenario/DebugRun.vue | 96 +- .../automation/scenario/EditApiScenario.vue | 50 +- .../api/automation/scenario/Setting.js | 53 +- .../scenario/common/ApiBaseComponent.vue | 2 +- .../scenario/common/MsPluginUpload.vue | 136 +++ .../scenario/component/ComponentConfig.vue | 322 ++++--- .../scenario/component/PluginComponent.vue | 287 ++++++ .../scenario/maximize/MaximizeScenario.vue | 2 +- .../api/automation/scenario/menu/Menu.js | 92 +- .../api/definition/components/Run.vue | 8 +- .../api/definition/model/ApiTestModel.js | 28 + .../components/settings/plugin/JarConfig.vue | 165 ++++ .../settings/plugin/PluginConfig.vue | 125 +++ .../components/settings/plugin/ScriptView.vue | 75 ++ .../business/components/settings/router.js | 15 +- frontend/src/business/main.js | 2 + frontend/src/i18n/en-US.js | 6 + frontend/src/i18n/zh-CN.js | 6 + frontend/src/i18n/zh-TW.js | 22 +- frontend/src/store/index.js | 1 + 84 files changed, 3309 insertions(+), 543 deletions(-) rename backend/src/main/java/io/metersphere/api/dto/definition/request/{MsTestElement.java => ElementUtil.java} (60%) create mode 100644 backend/src/main/java/io/metersphere/base/domain/Plugin.java create mode 100644 backend/src/main/java/io/metersphere/base/domain/PluginExample.java create mode 100644 backend/src/main/java/io/metersphere/base/domain/PluginWithBLOBs.java create mode 100644 backend/src/main/java/io/metersphere/base/mapper/PluginMapper.java create mode 100644 backend/src/main/java/io/metersphere/base/mapper/PluginMapper.xml create mode 100644 backend/src/main/java/io/metersphere/controller/PluginController.java create mode 100644 backend/src/main/java/io/metersphere/controller/request/PluginRequest.java create mode 100644 backend/src/main/java/io/metersphere/controller/request/PluginResourceDTO.java create mode 100644 backend/src/main/java/io/metersphere/service/PluginService.java create mode 100644 backend/src/main/java/io/metersphere/service/utils/CommonUtil.java create mode 100644 backend/src/main/resources/db/migration/V95__v1.13_release.sql create mode 100644 frontend/src/business/components/api/automation/scenario/common/MsPluginUpload.vue create mode 100644 frontend/src/business/components/api/automation/scenario/component/PluginComponent.vue create mode 100644 frontend/src/business/components/settings/plugin/JarConfig.vue create mode 100644 frontend/src/business/components/settings/plugin/PluginConfig.vue create mode 100644 frontend/src/business/components/settings/plugin/ScriptView.vue diff --git a/backend/pom.xml b/backend/pom.xml index 5cef77a038..d60566921a 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -440,6 +440,13 @@ xmindjbehaveplugin 0.8 + + + io.metersphere + metersphere-plugin-core + 1.0 + + diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java b/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java index e47b2ce9d8..1d6919da8e 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java @@ -1,6 +1,6 @@ package io.metersphere.api.dto.automation; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import lombok.Getter; import lombok.Setter; diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java index 13a73b9a1f..f9b5173e5e 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java @@ -5,7 +5,7 @@ import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.definition.parse.har.HarUtils; import io.metersphere.api.dto.definition.parse.har.model.*; import io.metersphere.api.dto.definition.request.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.jmeter.RequestResult; diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java index 549060a126..756acaa3d0 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java @@ -8,7 +8,7 @@ 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.definition.request.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.assertions.*; import io.metersphere.api.dto.definition.request.controller.MsLoopController; import io.metersphere.api.dto.definition.request.controller.MsTransactionController; diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java index 9f16baa44c..abe9011f61 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java @@ -7,7 +7,7 @@ import com.alibaba.fastjson.parser.Feature; import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.definition.parse.ms.NodeTree; import io.metersphere.api.dto.definition.request.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.parse.MsAbstractParser; import io.metersphere.api.service.ApiAutomationService; import io.metersphere.api.service.ApiTestCaseService; diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java index da669fc41b..2b14cb5ff6 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java @@ -3,7 +3,7 @@ package io.metersphere.api.dto.automation.parse; import com.alibaba.fastjson.JSON; import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.definition.request.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; import io.metersphere.api.dto.parse.postman.PostmanCollection; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java index 8b2759141d..8711424474 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java @@ -1,8 +1,8 @@ package io.metersphere.api.dto.definition; import io.metersphere.api.dto.automation.RunModeConfig; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.response.Response; +import io.metersphere.plugin.core.MsTestElement; import lombok.Getter; import lombok.Setter; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java index 484d2fbc42..7fc27ede0c 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiDefinitionRequest.java @@ -1,6 +1,6 @@ package io.metersphere.api.dto.definition; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.response.Response; import io.metersphere.base.domain.Schedule; import lombok.Getter; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java index 7beeedbd83..d6f03e3609 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/SaveApiTestCaseRequest.java @@ -1,6 +1,6 @@ package io.metersphere.api.dto.definition; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.base.domain.ApiTestCase; import lombok.Getter; import lombok.Setter; 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 index 1ff3a638fa..366acfa129 100644 --- 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 @@ -9,7 +9,6 @@ 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.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.assertions.*; import io.metersphere.api.dto.definition.request.extract.MsExtract; import io.metersphere.api.dto.definition.request.extract.MsExtractJSONPath; @@ -17,6 +16,7 @@ import io.metersphere.api.dto.definition.request.extract.MsExtractRegex; import io.metersphere.api.dto.definition.request.extract.MsExtractXPath; import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor; import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; +import io.metersphere.plugin.core.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; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/ElementUtil.java similarity index 60% rename from backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java rename to backend/src/main/java/io/metersphere/api/dto/definition/request/ElementUtil.java index c39ac942f8..dad0a8618e 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/ElementUtil.java @@ -1,28 +1,9 @@ package io.metersphere.api.dto.definition.request; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.annotation.JSONField; -import com.alibaba.fastjson.annotation.JSONType; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.metersphere.api.dto.definition.request.assertions.MsAssertions; -import io.metersphere.api.dto.definition.request.auth.MsAuthManager; -import io.metersphere.api.dto.definition.request.configurations.MsHeaderManager; -import io.metersphere.api.dto.definition.request.controller.MsIfController; import io.metersphere.api.dto.definition.request.controller.MsLoopController; import io.metersphere.api.dto.definition.request.controller.MsTransactionController; -import io.metersphere.api.dto.definition.request.extract.MsExtract; -import io.metersphere.api.dto.definition.request.processors.MsJSR223Processor; -import io.metersphere.api.dto.definition.request.processors.post.MsJDBCPostProcessor; -import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor; -import io.metersphere.api.dto.definition.request.processors.pre.MsJDBCPreProcessor; -import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; -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.timer.MsConstantTimer; -import io.metersphere.api.dto.definition.request.unknown.MsJmeterElement; import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; import io.metersphere.api.dto.mockconfig.MockConfigStaticData; import io.metersphere.api.dto.scenario.KeyValue; @@ -35,8 +16,7 @@ import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.FileUtils; -import io.metersphere.commons.utils.LogUtil; -import lombok.Data; +import io.metersphere.plugin.core.MsTestElement; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.jmeter.config.Arguments; @@ -46,120 +26,25 @@ import org.apache.jmeter.modifiers.CounterConfig; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; import org.apache.jorphan.collections.HashTree; -import org.apache.jorphan.collections.ListedHashTree; -import java.io.ByteArrayOutputStream; import java.io.File; import java.net.URL; import java.util.*; import java.util.stream.Collectors; -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type") -@JsonSubTypes({ - @JsonSubTypes.Type(value = MsHTTPSamplerProxy.class, name = "HTTPSamplerProxy"), - @JsonSubTypes.Type(value = MsHeaderManager.class, name = "HeaderManager"), - @JsonSubTypes.Type(value = MsJSR223Processor.class, name = "JSR223Processor"), - @JsonSubTypes.Type(value = MsJSR223PostProcessor.class, name = "JSR223PostProcessor"), - @JsonSubTypes.Type(value = MsJSR223PreProcessor.class, name = "JSR223PreProcessor"), - @JsonSubTypes.Type(value = MsJDBCPreProcessor.class, name = "JDBCPreProcessor"), - @JsonSubTypes.Type(value = MsJDBCPostProcessor.class, name = "JDBCPostProcessor"), - @JsonSubTypes.Type(value = MsTestPlan.class, name = "TestPlan"), - @JsonSubTypes.Type(value = MsThreadGroup.class, name = "ThreadGroup"), - @JsonSubTypes.Type(value = MsAuthManager.class, name = "AuthManager"), - @JsonSubTypes.Type(value = MsAssertions.class, name = "Assertions"), - @JsonSubTypes.Type(value = MsExtract.class, name = "Extract"), - @JsonSubTypes.Type(value = MsTCPSampler.class, name = "TCPSampler"), - @JsonSubTypes.Type(value = MsDubboSampler.class, name = "DubboSampler"), - @JsonSubTypes.Type(value = MsJDBCSampler.class, name = "JDBCSampler"), - @JsonSubTypes.Type(value = MsConstantTimer.class, name = "ConstantTimer"), - @JsonSubTypes.Type(value = MsIfController.class, name = "IfController"), - @JsonSubTypes.Type(value = MsTransactionController.class, name = "TransactionController"), - @JsonSubTypes.Type(value = MsScenario.class, name = "scenario"), - @JsonSubTypes.Type(value = MsLoopController.class, name = "LoopController"), - @JsonSubTypes.Type(value = MsJmeterElement.class, name = "JmeterElement"), - -}) -@JSONType(seeAlso = {MsHTTPSamplerProxy.class, MsHeaderManager.class, MsJSR223Processor.class, MsJSR223PostProcessor.class, MsJDBCPreProcessor.class, MsJDBCPostProcessor.class, - MsJSR223PreProcessor.class, MsTestPlan.class, MsThreadGroup.class, MsAuthManager.class, MsAssertions.class, - MsExtract.class, MsTCPSampler.class, MsDubboSampler.class, MsJDBCSampler.class, MsConstantTimer.class, MsIfController.class, MsTransactionController.class, MsScenario.class, MsLoopController.class, MsJmeterElement.class}, typeKey = "type") -@Data -public abstract class MsTestElement { - private String type; - @JSONField(ordinal = 1) - private String id; - @JSONField(ordinal = 2) - private String name; - @JSONField(ordinal = 3) - private String label; - @JSONField(ordinal = 4) - private String resourceId; - @JSONField(ordinal = 5) - private String referenced; - @JSONField(ordinal = 6) - private boolean active; - @JSONField(ordinal = 7) - private String index; - @JSONField(ordinal = 8) - private boolean enable = true; - @JSONField(ordinal = 9) - private String refType; - @JSONField(ordinal = 10) - private LinkedList hashTree; - @JSONField(ordinal = 11) - private boolean customizeReq; - @JSONField(ordinal = 12) - private String projectId; - @JSONField(ordinal = 13) - private boolean isMockEnvironment; - @JSONField(ordinal = 14) - private String environmentId; - private MsTestElement parent; +public class ElementUtil { private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR; - /** - * todo 公共环境逐层传递,如果自身有环境 以自身引用环境为准否则以公共环境作为请求环境 - */ - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { - if (CollectionUtils.isNotEmpty(hashTree)) { - for (MsTestElement el : hashTree) { - el.toHashTree(tree, el.hashTree, config); - } - } - } - - /** - * 转换JMX - * - * @param hashTree - * @return - */ - public String getJmx(HashTree hashTree) { - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - SaveService.saveTree(hashTree, baos); - return baos.toString(); - } catch (Exception e) { - e.printStackTrace(); - LogUtil.warn("HashTree error, can't log jmx scenarioDefinition"); - } - return null; - } - - public HashTree generateHashTree(ParameterConfig config) { - HashTree jmeterTestPlanHashTree = new ListedHashTree(); - this.toHashTree(jmeterTestPlanHashTree, this.hashTree, config); - return jmeterTestPlanHashTree; - } - - public Arguments addArguments(ParameterConfig config) { - if (config.isEffective(this.getProjectId()) && config.getConfig().get(this.getProjectId()).getCommonConfig() != null - && CollectionUtils.isNotEmpty(config.getConfig().get(this.getProjectId()).getCommonConfig().getVariables())) { + public static Arguments addArguments(ParameterConfig config, String projectId, String name) { + if (config.isEffective(projectId) && config.getConfig().get(projectId).getCommonConfig() != null + && CollectionUtils.isNotEmpty(config.getConfig().get(projectId).getCommonConfig().getVariables())) { Arguments arguments = new Arguments(); arguments.setEnabled(true); - arguments.setName(StringUtils.isNoneBlank(this.getName()) ? this.getName() : "Arguments"); + arguments.setName(StringUtils.isNoneBlank(name) ? name : "Arguments"); arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName()); arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ArgumentsPanel")); - config.getConfig().get(this.getProjectId()).getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> + config.getConfig().get(projectId).getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=") ); if (arguments.getArguments().size() > 0) { @@ -169,7 +54,7 @@ public abstract class MsTestElement { return null; } - protected Map getEnvironmentConfig(String environmentId) { + public static Map getEnvironmentConfig(String environmentId, String projectId, boolean isMockEnvironment) { ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentId); if (environment != null && environment.getConfig() != null) { @@ -178,7 +63,7 @@ public abstract class MsTestElement { } // 单独接口执行 Map map = new HashMap<>(); - map.put(this.getProjectId(), JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class)); + map.put(projectId, JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class)); return map; } @@ -186,7 +71,7 @@ public abstract class MsTestElement { return null; } - protected void addCsvDataSet(HashTree tree, List variables, ParameterConfig config, String shareMode) { + public static void addCsvDataSet(HashTree tree, List variables, ParameterConfig config, String shareMode) { if (CollectionUtils.isNotEmpty(variables)) { List list = variables.stream().filter(ScenarioVariable::isCSVValid).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { @@ -215,7 +100,7 @@ public abstract class MsTestElement { } } - protected void addCounter(HashTree tree, List variables) { + public static void addCounter(HashTree tree, List variables) { if (CollectionUtils.isNotEmpty(variables)) { List list = variables.stream().filter(ScenarioVariable::isCounterValid).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { @@ -237,7 +122,7 @@ public abstract class MsTestElement { } } - protected void addRandom(HashTree tree, List variables) { + public static void addRandom(HashTree tree, List variables) { if (CollectionUtils.isNotEmpty(variables)) { List list = variables.stream().filter(ScenarioVariable::isRandom).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { @@ -258,7 +143,7 @@ public abstract class MsTestElement { } } - public String getFullPath(MsTestElement element, String path) { + public static String getFullPath(MsTestElement element, String path) { if (element.getParent() == null) { return path; } @@ -279,7 +164,7 @@ public abstract class MsTestElement { return getFullPath(element.getParent(), path); } - public void getScenarioSet(MsTestElement element, List id_names) { + public static void getScenarioSet(MsTestElement element, List id_names) { if (StringUtils.equals(element.getType(), "scenario")) { id_names.add(element.getResourceId() + "_" + element.getName()); } @@ -289,7 +174,7 @@ public abstract class MsTestElement { getScenarioSet(element.getParent(), id_names); } - protected String getParentName(MsTestElement parent) { + public static String getParentName(MsTestElement parent) { if (parent != null) { // if (MsTestElementConstants.TransactionController.name().equals(parent.getType())) { // MsTransactionController transactionController = (MsTransactionController) parent; @@ -308,7 +193,7 @@ public abstract class MsTestElement { return ""; } - public String getFullIndexPath(MsTestElement element, String path) { + public static String getFullIndexPath(MsTestElement element, String path) { if (element == null || element.getParent() == null) { return path; } @@ -316,7 +201,7 @@ public abstract class MsTestElement { return getFullIndexPath(element.getParent(), path); } - public boolean isURL(String str) { + public static boolean isURL(String str) { try { if (StringUtils.isEmpty(str)) { return false; @@ -350,9 +235,55 @@ public abstract class MsTestElement { } return requests; } + + + public final static HashMap clazzMap = new HashMap() { + { + put("scenario", "io.metersphere.api.dto.definition.request.MsScenario"); + put("HTTPSamplerProxy", "io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy"); + put("DubboSampler", "io.metersphere.api.dto.definition.request.sampler.MsDubboSampler"); + put("JDBCSampler", "io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler"); + put("TCPSampler", "io.metersphere.api.dto.definition.request.sampler.MsTCPSampler"); + put("IfController", "io.metersphere.api.dto.definition.request.controller.MsIfController"); + put("TransactionController", "io.metersphere.api.dto.definition.request.controller.MsTransactionController"); + put("LoopController", "io.metersphere.api.dto.definition.request.controller.MsLoopController"); + put("ConstantTimer", "io.metersphere.api.dto.definition.request.timer.MsConstantTimer"); + put("JSR223Processor", "io.metersphere.api.dto.definition.request.processors.MsJSR223Processor"); + put("JSR223PreProcessor", "io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor"); + put("JSR223PostProcessor", "io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor"); + put("JDBCPreProcessor", "io.metersphere.api.dto.definition.request.processors.pre.MsJDBCPreProcessor"); + put("JDBCPostProcessor", "io.metersphere.api.dto.definition.request.processors.post.MsJDBCPostProcessor"); + put("Assertions", "io.metersphere.api.dto.definition.request.assertions.MsAssertions"); + put("Extract", "io.metersphere.api.dto.definition.request.extract.MsExtract"); + put("JmeterElement", "io.metersphere.api.dto.definition.request.unknown.MsJmeterElement"); + put("TestPlan", "io.metersphere.api.dto.definition.request.MsTestPlan"); + put("ThreadGroup", "io.metersphere.api.dto.definition.request.MsThreadGroup"); + put("DNSCacheManager", "io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager"); + put("DebugSampler", "io.metersphere.api.dto.definition.request.sampler.MsDebugSampler"); + + } + }; + + public static void dataFormatting(JSONArray hashTree) { + for (int i = 0; i < hashTree.size(); i++) { + JSONObject element = hashTree.getJSONObject(i); + if (element != null && element.get("clazzName") == null && clazzMap.containsKey(element.getString("type"))) { + element.fluentPut("clazzName", clazzMap.get(element.getString("type"))); + } + if (element.containsKey("hashTree")) { + JSONArray elementJSONArray = element.getJSONArray("hashTree"); + dataFormatting(elementJSONArray); + } + } + } + + public static void dataFormatting(JSONObject element) { + if (element != null && element.get("clazzName") == null && clazzMap.containsKey(element.getString("type"))) { + element.fluentPut("clazzName", clazzMap.get(element.getString("type"))); + } + if (element != null && element.containsKey("hashTree")) { + JSONArray elementJSONArray = element.getJSONArray("hashTree"); + dataFormatting(elementJSONArray); + } + } } - - - - - diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java index bde7a7dcde..dad8a24edd 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java @@ -19,6 +19,8 @@ import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.constants.RunModeConstants; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.FileUtils; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -42,6 +44,7 @@ import java.util.stream.Collectors; public class MsScenario extends MsTestElement { private String type = "scenario"; + private String clazzName = "io.metersphere.api.dto.definition.request.MsScenario"; @JSONField(ordinal = 21) private String referenced; @@ -77,7 +80,8 @@ public class MsScenario extends MsTestElement { } @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; @@ -92,6 +96,8 @@ public class MsScenario extends MsTestElement { ApiScenarioWithBLOBs scenario = apiAutomationService.getApiScenario(this.getId()); if (scenario != null && StringUtils.isNotEmpty(scenario.getScenarioDefinition())) { JSONObject element = JSON.parseObject(scenario.getScenarioDefinition()); + // 历史数据处理 + ElementUtil.dataFormatting(element.getJSONArray("hashTree")); this.setName(scenario.getName()); this.setProjectId(scenario.getProjectId()); hashTree = mapper.readValue(element.getString("hashTree"), new TypeReference>() { @@ -161,9 +167,9 @@ public class MsScenario extends MsTestElement { if (arguments != null) { tree.add(ParameterConfig.valueSupposeMock(arguments)); } - this.addCsvDataSet(tree, variables, config, "shareMode.group"); - this.addCounter(tree, variables); - this.addRandom(tree, variables); + ElementUtil.addCsvDataSet(tree, variables, config, "shareMode.group"); + ElementUtil.addCounter(tree, variables); + ElementUtil.addRandom(tree, variables); if (CollectionUtils.isNotEmpty(this.headers)) { //setHeader(tree, this.headers); config.setHeaders(this.headers); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestPlan.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestPlan.java index ab31d8a94c..474cf6222d 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestPlan.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestPlan.java @@ -2,6 +2,8 @@ package io.metersphere.api.dto.definition.request; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.annotation.JSONType; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -18,10 +20,13 @@ import java.util.List; @JSONType(typeName = "TestPlan") public class MsTestPlan extends MsTestElement { private String type = "TestPlan"; + private String clazzName = "io.metersphere.api.dto.definition.request.MsTestPlan"; + private boolean serializeThreadgroups = false; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; final HashTree testPlanTree = tree.add(getPlan()); if (CollectionUtils.isNotEmpty(hashTree)) { hashTree.forEach(el -> { diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java index 3e194c35dd..19a33d5223 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java @@ -3,6 +3,8 @@ package io.metersphere.api.dto.definition.request; import com.alibaba.fastjson.annotation.JSONType; import io.metersphere.api.dto.RunningParamKeys; import io.metersphere.api.dto.definition.request.sampler.MsDebugSampler; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -20,11 +22,14 @@ import java.util.List; @JSONType(typeName = "ThreadGroup") public class MsThreadGroup extends MsTestElement { private String type = "ThreadGroup"; + private String clazzName = "io.metersphere.api.dto.definition.request.MsThreadGroup"; + private boolean enableCookieShare; private Boolean onSampleError; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; final HashTree groupTree = tree.add(getThreadGroup()); if ((config != null && config.isEnableCookieShare()) || enableCookieShare) { CookieManager cookieManager = new CookieManager(); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/OldVersionUtil.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/OldVersionUtil.java index 943f5502a8..4205437ad7 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/OldVersionUtil.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/OldVersionUtil.java @@ -2,6 +2,7 @@ package io.metersphere.api.dto.definition.request; import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.plugin.core.MsTestElement; import org.apache.commons.lang3.StringUtils; import java.util.List; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java index 67625356c5..bc14915f58 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java @@ -5,6 +5,7 @@ import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.dto.ssl.MsKeyStore; import io.metersphere.jmeter.utils.ScriptEngineUtils; +import io.metersphere.plugin.core.MsParameter; import lombok.Data; import org.apache.jmeter.config.Arguments; @@ -14,7 +15,7 @@ import java.util.List; import java.util.Map; @Data -public class ParameterConfig { +public class ParameterConfig extends MsParameter { /** * 环境配置 */ diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java index 0ffc39dae5..af4f7851f6 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java @@ -1,8 +1,9 @@ package io.metersphere.api.dto.definition.request.assertions; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -18,6 +19,8 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @JSONType(typeName = "Assertions") public class MsAssertions extends MsTestElement { + private String clazzName = "io.metersphere.api.dto.definition.request.assertions.MsAssertions"; + private List regex; private List jsonPath; private List jsr223; @@ -26,7 +29,8 @@ public class MsAssertions extends MsTestElement { private String type = "Assertions"; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/auth/MsAuthManager.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/auth/MsAuthManager.java index abbce6821b..8fbbea9d70 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/auth/MsAuthManager.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/auth/MsAuthManager.java @@ -2,8 +2,9 @@ package io.metersphere.api.dto.definition.request.auth; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.lang3.StringUtils; @@ -21,6 +22,8 @@ import java.util.List; @JSONType(typeName = "AuthManager") public class MsAuthManager extends MsTestElement { private String type = "AuthManager"; + private String clazzName = "io.metersphere.api.dto.definition.request.auth.MsAuthManager"; + @JSONField(ordinal = 20) private String username; @@ -49,10 +52,11 @@ public class MsAuthManager extends MsTestElement { private String environment; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { if (!this.isEnable()) { return; } + ParameterConfig config = (ParameterConfig) msParameter; AuthManager authManager = new AuthManager(); authManager.setEnabled(true); authManager.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : "AuthManager"); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/configurations/MsHeaderManager.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/configurations/MsHeaderManager.java index d1d9bb5098..2ffb7fbb3d 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/configurations/MsHeaderManager.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/configurations/MsHeaderManager.java @@ -2,9 +2,10 @@ package io.metersphere.api.dto.definition.request.configurations; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.KeyValue; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -23,11 +24,14 @@ import java.util.List; public class MsHeaderManager extends MsTestElement { private String type = "HeaderManager"; + private String clazzName = "io.metersphere.api.dto.definition.request.configurations.MsHeaderManager"; + @JSONField(ordinal = 20) private List headers; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; HeaderManager headerManager = new HeaderManager(); headerManager.setEnabled(this.isEnable()); headerManager.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() + "HeaderManager" : "HeaderManager"); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java index bcd8b26a4f..5247731ebd 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java @@ -1,8 +1,9 @@ package io.metersphere.api.dto.definition.request.controller; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -21,6 +22,8 @@ import java.util.regex.Pattern; @JSONType(typeName = "IfController") public class MsIfController extends MsTestElement { private String type = "IfController"; + private String clazzName = "io.metersphere.api.dto.definition.request.controller.MsIfController"; + private String id; private String variable; private String operator; @@ -28,7 +31,8 @@ public class MsIfController extends MsTestElement { private String remark; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java index 1dafd69222..8e9e64510d 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java @@ -2,12 +2,14 @@ package io.metersphere.api.dto.definition.request.controller; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.controller.loop.CountController; import io.metersphere.api.dto.definition.request.controller.loop.MsForEachController; import io.metersphere.api.dto.definition.request.controller.loop.MsWhileController; import io.metersphere.commons.constants.LoopConstants; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -30,6 +32,8 @@ import java.util.UUID; @JSONType(typeName = "LoopController") public class MsLoopController extends MsTestElement { private String type = "LoopController"; + private String clazzName = "io.metersphere.api.dto.definition.request.controller.MsLoopController"; + @JSONField(ordinal = 20) private String loopType; @@ -46,16 +50,18 @@ public class MsLoopController extends MsTestElement { private String ms_current_timer = UUID.randomUUID().toString(); @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; + // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; } final HashTree groupTree = controller(tree); if (CollectionUtils.isNotEmpty(config.getVariables())) { - this.addCsvDataSet(groupTree, config.getVariables(), config, "shareMode.thread"); - this.addCounter(groupTree, config.getVariables()); - this.addRandom(groupTree, config.getVariables()); + ElementUtil.addCsvDataSet(groupTree, config.getVariables(), config, "shareMode.thread"); + ElementUtil.addCounter(groupTree, config.getVariables()); + ElementUtil.addRandom(groupTree, config.getVariables()); } // 循环下都增加一个计数器,用于结果统计 diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsTransactionController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsTransactionController.java index e42ea5f506..4237766d02 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsTransactionController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsTransactionController.java @@ -1,14 +1,15 @@ package io.metersphere.api.dto.definition.request.controller; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.commons.constants.DelimiterConstants; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.jmeter.control.IfController; import org.apache.jmeter.control.TransactionController; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; @@ -21,19 +22,22 @@ import java.util.List; @JSONType(typeName = "TransactionController") public class MsTransactionController extends MsTestElement { private String type = "TransactionController"; + private String clazzName = "io.metersphere.api.dto.definition.request.controller.MsTransactionController"; + private String name; private boolean generateParentSample; private boolean includeTimers; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; } TransactionController transactionController = transactionController(); - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { transactionController.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java index 88db977993..5a36f8e1ff 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java @@ -1,12 +1,13 @@ package io.metersphere.api.dto.definition.request.dns; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.HttpConfig; import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.dto.scenario.environment.Host; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -24,9 +25,11 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @JSONType(typeName = "DNSCacheManager") public class MsDNSCacheManager extends MsTestElement { + private String clazzName = "io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager"; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java index e58d422847..f5e05c241b 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java @@ -1,8 +1,9 @@ package io.metersphere.api.dto.definition.request.extract; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -23,13 +24,16 @@ import java.util.StringJoiner; @EqualsAndHashCode(callSuper = true) @JSONType(typeName = "Extract") public class MsExtract extends MsTestElement { + private String clazzName = "io.metersphere.api.dto.definition.request.extract.MsExtract"; + private List regex; private List json; private List xpath; private String type = "Extract"; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java index a52a89de4b..e57162f749 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java @@ -4,10 +4,12 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import io.metersphere.api.dto.RunningParamKeys; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.commons.constants.DelimiterConstants; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -26,6 +28,7 @@ import java.util.List; @JSONType(typeName = "JSR223Processor") public class MsJSR223Processor extends MsTestElement { private String type = "JSR223Processor"; + private String clazzName = "io.metersphere.api.dto.definition.request.processors.MsJSR223Processor"; @JSONField(ordinal = 20) private String script; @@ -34,7 +37,8 @@ public class MsJSR223Processor extends MsTestElement { private String scriptLanguage; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; //替换Metersphere环境变量 if(StringUtils.isEmpty(this.getEnvironmentId())){ if(config.getConfig() != null){ @@ -67,14 +71,14 @@ public class MsJSR223Processor extends MsTestElement { } else { processor.setName("JSR223Processor"); } - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { processor.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } processor.setProperty("MS-ID", this.getId()); processor.setProperty("MS-RESOURCE-ID", this.getResourceId()+ "_" + this.getIndex()); List id_names = new LinkedList<>(); - this.getScenarioSet(this, id_names); + ElementUtil.getScenarioSet(this, id_names); processor.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); processor.setProperty(TestElement.TEST_CLASS, JSR223Sampler.class.getName()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJDBCPostProcessor.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJDBCPostProcessor.java index aefa2fb72e..597a01dc30 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJDBCPostProcessor.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJDBCPostProcessor.java @@ -7,7 +7,7 @@ import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.DatabaseConfig; import io.metersphere.api.dto.scenario.KeyValue; @@ -24,6 +24,8 @@ import io.metersphere.commons.constants.RunModeConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -50,6 +52,8 @@ import java.util.stream.Collectors; public class MsJDBCPostProcessor extends MsTestElement { // type 必须放最前面,以便能够转换正确的类 private String type = "JDBCPostProcessor"; + private String clazzName = "io.metersphere.api.dto.definition.request.processors.post.MsJDBCPostProcessor"; + @JSONField(ordinal = 20) private DatabaseConfig dataSource; @JSONField(ordinal = 21) @@ -73,7 +77,8 @@ public class MsJDBCPostProcessor extends MsTestElement { private String useEnvironment; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; @@ -84,7 +89,7 @@ public class MsJDBCPostProcessor extends MsTestElement { if (config.getConfig() == null) { // 单独接口执行 this.setProjectId(config.getProjectId()); - config.setConfig(getEnvironmentConfig(StringUtils.isNotEmpty(useEnvironment) ? useEnvironment : environmentId)); + config.setConfig(ElementUtil.getEnvironmentConfig(StringUtils.isNotEmpty(useEnvironment) ? useEnvironment : environmentId, this.getProjectId(), this.isMockEnvironment())); } // 数据兼容处理 @@ -108,7 +113,7 @@ public class MsJDBCPostProcessor extends MsTestElement { } } //如果当前数据源为null,则获取已选环境的数据源 - if(this.dataSource == null){ + if (this.dataSource == null) { // 自选了数据源 if (config.isEffective(this.getProjectId()) && CollectionUtils.isNotEmpty(config.getConfig().get(this.getProjectId()).getDatabaseConfigs()) && isDataSource(config.getConfig().get(this.getProjectId()).getDatabaseConfigs())) { @@ -174,7 +179,9 @@ public class MsJDBCPostProcessor extends MsTestElement { if (bloBs != null) { this.setName(bloBs.getName()); this.setProjectId(bloBs.getProjectId()); - proxy = mapper.readValue(bloBs.getRequest(), new TypeReference() { + JSONObject element = JSON.parseObject(bloBs.getRequest()); + ElementUtil.dataFormatting(element); + proxy = mapper.readValue(element.toJSONString(), new TypeReference() { }); } } else { @@ -237,7 +244,7 @@ public class MsJDBCPostProcessor extends MsTestElement { JDBCPostProcessor jdbcPostProcessor = new JDBCPostProcessor(); jdbcPostProcessor.setEnabled(this.isEnable()); jdbcPostProcessor.setName(this.getName() == null? "JDBCPostProcessor" : this.getName()); - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { jdbcPostProcessor.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } @@ -245,9 +252,9 @@ public class MsJDBCPostProcessor extends MsTestElement { jdbcPostProcessor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); jdbcPostProcessor.setProperty("MS-ID", this.getId()); String indexPath = this.getIndex(); - jdbcPostProcessor.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + this.getFullIndexPath(this.getParent(), indexPath)); + jdbcPostProcessor.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + ElementUtil.getFullIndexPath(this.getParent(), indexPath)); List id_names = new LinkedList<>(); - this.getScenarioSet(this, id_names); + ElementUtil.getScenarioSet(this, id_names); jdbcPostProcessor.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); // request.getDataSource() 是ID,需要转换为Name diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJSR223PostProcessor.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJSR223PostProcessor.java index 02b7f0f712..7959876cf9 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJSR223PostProcessor.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/post/MsJSR223PostProcessor.java @@ -3,9 +3,10 @@ package io.metersphere.api.dto.definition.request.processors.post; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import io.metersphere.api.dto.RunningParamKeys; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -23,6 +24,7 @@ import java.util.List; @JSONType(typeName = "JSR223PostProcessor") public class MsJSR223PostProcessor extends MsTestElement { private String type = "JSR223PostProcessor"; + private String clazzName = "io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor"; @JSONField(ordinal = 20) private String script; @@ -31,7 +33,8 @@ public class MsJSR223PostProcessor extends MsTestElement { private String scriptLanguage; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; if(StringUtils.isEmpty(this.getEnvironmentId())){ if(config.getConfig() != null){ if(config.getProjectId() != null){ diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJDBCPreProcessor.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJDBCPreProcessor.java index ee7790f465..b15026579e 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJDBCPreProcessor.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJDBCPreProcessor.java @@ -7,7 +7,7 @@ import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.DatabaseConfig; import io.metersphere.api.dto.scenario.KeyValue; @@ -24,6 +24,8 @@ import io.metersphere.commons.constants.RunModeConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -50,6 +52,8 @@ import java.util.stream.Collectors; public class MsJDBCPreProcessor extends MsTestElement { // type 必须放最前面,以便能够转换正确的类 private String type = "JDBCPreProcessor"; + private String clazzName = "io.metersphere.api.dto.definition.request.processors.pre.MsJDBCPreProcessor"; + @JSONField(ordinal = 20) private DatabaseConfig dataSource; @JSONField(ordinal = 21) @@ -73,7 +77,8 @@ public class MsJDBCPreProcessor extends MsTestElement { private String useEnvironment; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; @@ -84,7 +89,7 @@ public class MsJDBCPreProcessor extends MsTestElement { if (config.getConfig() == null) { // 单独接口执行 this.setProjectId(config.getProjectId()); - config.setConfig(getEnvironmentConfig(StringUtils.isNotEmpty(useEnvironment) ? useEnvironment : environmentId)); + config.setConfig(ElementUtil.getEnvironmentConfig(StringUtils.isNotEmpty(useEnvironment) ? useEnvironment : environmentId, this.getProjectId(), isMockEnvironment())); } // 数据兼容处理 @@ -108,7 +113,7 @@ public class MsJDBCPreProcessor extends MsTestElement { } } //如果当前数据源为null,则获取已选环境的数据源 - if(this.dataSource == null){ + if (this.dataSource == null) { // 自选了数据源 if (config.isEffective(this.getProjectId()) && CollectionUtils.isNotEmpty(config.getConfig().get(this.getProjectId()).getDatabaseConfigs()) && isDataSource(config.getConfig().get(this.getProjectId()).getDatabaseConfigs())) { @@ -174,7 +179,9 @@ public class MsJDBCPreProcessor extends MsTestElement { if (bloBs != null) { this.setName(bloBs.getName()); this.setProjectId(bloBs.getProjectId()); - proxy = mapper.readValue(bloBs.getRequest(), new TypeReference() { + JSONObject element = JSON.parseObject(bloBs.getRequest()); + ElementUtil.dataFormatting(element); + proxy = mapper.readValue(element.toJSONString(), new TypeReference() { }); } } else { @@ -237,7 +244,7 @@ public class MsJDBCPreProcessor extends MsTestElement { JDBCPreProcessor jdbcPreProcessor = new JDBCPreProcessor(); jdbcPreProcessor.setEnabled(this.isEnable()); jdbcPreProcessor.setName(this.getName() == null? "JDBCPreProcessor" : this.getName()); - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { jdbcPreProcessor.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } @@ -245,9 +252,9 @@ public class MsJDBCPreProcessor extends MsTestElement { jdbcPreProcessor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); jdbcPreProcessor.setProperty("MS-ID", this.getId()); String indexPath = this.getIndex(); - jdbcPreProcessor.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + this.getFullIndexPath(this.getParent(), indexPath)); + jdbcPreProcessor.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + ElementUtil.getFullIndexPath(this.getParent(), indexPath)); List id_names = new LinkedList<>(); - this.getScenarioSet(this, id_names); + ElementUtil.getScenarioSet(this, id_names); jdbcPreProcessor.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); // request.getDataSource() 是ID,需要转换为Name diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java index e609bc77f8..ad3b726e06 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java @@ -3,9 +3,10 @@ package io.metersphere.api.dto.definition.request.processors.pre; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import io.metersphere.api.dto.RunningParamKeys; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -23,6 +24,7 @@ import java.util.List; @JSONType(typeName = "JSR223PreProcessor") public class MsJSR223PreProcessor extends MsTestElement { private String type = "JSR223PreProcessor"; + private String clazzName = "io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor"; @JSONField(ordinal = 20) private String script; @@ -31,7 +33,8 @@ public class MsJSR223PreProcessor extends MsTestElement { private String scriptLanguage; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; if(StringUtils.isEmpty(this.getEnvironmentId())){ if(config.getConfig() != null){ if(config.getProjectId() != null){ diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDebugSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDebugSampler.java index 94e8db52e4..d4e79844b5 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDebugSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDebugSampler.java @@ -2,8 +2,9 @@ package io.metersphere.api.dto.definition.request.sampler; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -19,6 +20,8 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @JSONType(typeName = "DebugSampler") public class MsDebugSampler extends MsTestElement { + private String clazzName = "io.metersphere.api.dto.definition.request.sampler.MsDebugSampler"; + @JSONField(ordinal = 40) private String type = "DebugSampler"; @JSONField(ordinal = 41) @@ -29,7 +32,8 @@ public class MsDebugSampler extends MsTestElement { private boolean displaySystemProperties = false; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java index a11a81f1f6..b3e6c0c9d9 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java @@ -1,6 +1,7 @@ package io.metersphere.api.dto.definition.request.sampler; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.annotation.JsonProperty; @@ -10,7 +11,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; 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.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.sampler.dubbo.MsConfigCenter; import io.metersphere.api.dto.definition.request.sampler.dubbo.MsConsumerAndService; @@ -24,6 +25,8 @@ import io.metersphere.commons.constants.DelimiterConstants; import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -41,6 +44,8 @@ import java.util.stream.Collectors; @EqualsAndHashCode(callSuper = true) @JSONType(typeName = "DubboSampler") public class MsDubboSampler extends MsTestElement { + private String clazzName = "io.metersphere.api.dto.definition.request.sampler.MsDubboSampler"; + /** * type 必须放最前面,以便能够转换正确的类 */ @@ -69,8 +74,13 @@ public class MsDubboSampler extends MsTestElement { @JSONField(ordinal = 60) private String useEnvironment; + @JSONField(ordinal = 61) + private boolean customizeReq; + + @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; @@ -101,7 +111,9 @@ public class MsDubboSampler extends MsTestElement { ApiTestCaseWithBLOBs bloBs = apiTestCaseService.get(this.getId()); if (bloBs != null) { this.setProjectId(bloBs.getProjectId()); - proxy = mapper.readValue(bloBs.getRequest(), new TypeReference() { + JSONObject element = JSON.parseObject(bloBs.getRequest()); + ElementUtil.dataFormatting(element); + proxy = mapper.readValue(element.toJSONString(), new TypeReference() { }); this.setName(bloBs.getName()); } @@ -134,7 +146,7 @@ public class MsDubboSampler extends MsTestElement { DubboSample sampler = new DubboSample(); sampler.setEnabled(this.isEnable()); sampler.setName(this.getName()); - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { sampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } @@ -142,9 +154,9 @@ public class MsDubboSampler extends MsTestElement { sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("DubboSampleGui")); sampler.setProperty("MS-ID", this.getId()); String indexPath = this.getIndex(); - sampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + this.getFullIndexPath(this.getParent(), indexPath)); + sampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + ElementUtil.getFullIndexPath(this.getParent(), indexPath)); List id_names = new LinkedList<>(); - this.getScenarioSet(this, id_names); + ElementUtil.getScenarioSet(this, id_names); sampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); sampler.addTestElement(configCenter(this.getConfigCenter())); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java index 3680871489..90a1a31348 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java @@ -7,7 +7,7 @@ import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.auth.MsAuthManager; import io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager; @@ -38,6 +38,8 @@ import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.FileUtils; import io.metersphere.commons.utils.LogUtil; import io.metersphere.jmeter.utils.ScriptEngineUtils; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.track.service.TestPlanApiCaseService; import lombok.Data; import lombok.EqualsAndHashCode; @@ -68,6 +70,7 @@ import java.util.stream.Collectors; @JSONType(typeName = "HTTPSamplerProxy") public class MsHTTPSamplerProxy extends MsTestElement { private String type = "HTTPSamplerProxy"; + private String clazzName = "io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy"; @JSONField(ordinal = 20) private String protocol; @@ -122,10 +125,13 @@ public class MsHTTPSamplerProxy extends MsTestElement { @JSONField(ordinal = 38) private String alias; - + + @JSONField(ordinal = 39) + private boolean customizeReq; + private MsJSR223PreProcessor preProcessor; private MsJSR223PostProcessor postProcessor; - + private void setRefElement() { try { ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class); @@ -137,7 +143,9 @@ public class MsHTTPSamplerProxy extends MsTestElement { ApiTestCaseWithBLOBs bloBs = apiTestCaseService.get(this.getId()); if (bloBs != null) { this.setProjectId(bloBs.getProjectId()); - proxy = mapper.readValue(bloBs.getRequest(), new TypeReference() { + JSONObject element = JSON.parseObject(bloBs.getRequest()); + ElementUtil.dataFormatting(element); + proxy = mapper.readValue(element.toJSONString(), new TypeReference() { }); this.setName(bloBs.getName()); } @@ -165,7 +173,8 @@ public class MsHTTPSamplerProxy extends MsTestElement { } @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; if (StringUtils.isEmpty(this.getEnvironmentId())) { this.setEnvironmentId(this.useEnvironment); } @@ -183,7 +192,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { if (StringUtils.isEmpty(this.getName())) { sampler.setName("HTTPSamplerProxy"); } - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { sampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } @@ -191,9 +200,9 @@ public class MsHTTPSamplerProxy extends MsTestElement { sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("HttpTestSampleGui")); sampler.setProperty("MS-ID", this.getId()); String indexPath = this.getIndex(); - sampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + this.getFullIndexPath(this.getParent(), indexPath)); + sampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + ElementUtil.getFullIndexPath(this.getParent(), indexPath)); List id_names = new LinkedList<>(); - this.getScenarioSet(this, id_names); + ElementUtil.getScenarioSet(this, id_names); sampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); sampler.setMethod(this.getMethod()); @@ -204,7 +213,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { if (config.getConfig() == null) { // 单独接口执行 this.setProjectId(config.getProjectId()); - config.setConfig(getEnvironmentConfig(useEnvironment)); + config.setConfig(ElementUtil.getEnvironmentConfig(this.useEnvironment, this.getProjectId(), this.isMockEnvironment())); } compatible(config); @@ -355,7 +364,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { private void setSamplerPath(ParameterConfig config, HttpConfig httpConfig, HTTPSamplerProxy sampler) { try { if (config.isEffective(this.getProjectId())) { - if (httpConfig == null && !isURL(this.getUrl())) { + if (httpConfig == null && !ElementUtil.isURL(this.getUrl())) { MSException.throwException("未匹配到环境,请检查环境配置"); } if (StringUtils.isEmpty(httpConfig.getProtocol())) { @@ -367,7 +376,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { String url = httpConfig.getProtocol() + "://" + httpConfig.getSocket(); // 补充如果是完整URL 则用自身URL - if (StringUtils.isNotEmpty(this.getUrl()) && isURL(this.getUrl())) { + if (StringUtils.isNotEmpty(this.getUrl()) && ElementUtil.isURL(this.getUrl())) { url = this.getUrl(); } @@ -588,7 +597,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { } return true; } - if (StringUtils.isNotEmpty(this.getUrl()) && isURL(this.getUrl())) { + if (StringUtils.isNotEmpty(this.getUrl()) && ElementUtil.isURL(this.getUrl())) { return true; } return false; @@ -817,7 +826,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { } public static List findHttpSampleFromHashTree(MsTestElement hashTree) { - return findFromHashTreeByType(hashTree, MsHTTPSamplerProxy.class, null); + return ElementUtil.findFromHashTreeByType(hashTree, MsHTTPSamplerProxy.class, null); } } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java index 66eac6bc47..23894b4732 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java @@ -7,7 +7,7 @@ import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor; import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; @@ -26,6 +26,8 @@ import io.metersphere.commons.constants.RunModeConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -48,6 +50,8 @@ import java.util.stream.Collectors; public class MsJDBCSampler extends MsTestElement { // type 必须放最前面,以便能够转换正确的类 private String type = "JDBCSampler"; + private String clazzName = "io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler"; + @JSONField(ordinal = 20) private DatabaseConfig dataSource; @JSONField(ordinal = 21) @@ -70,11 +74,15 @@ public class MsJDBCSampler extends MsTestElement { @JSONField(ordinal = 30) private String useEnvironment; + @JSONField(ordinal = 31) + private boolean customizeReq; + private MsJSR223PreProcessor preProcessor; private MsJSR223PostProcessor postProcessor; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; @@ -85,7 +93,7 @@ public class MsJDBCSampler extends MsTestElement { if (config.getConfig() == null) { // 单独接口执行 this.setProjectId(config.getProjectId()); - config.setConfig(getEnvironmentConfig(StringUtils.isNotEmpty(useEnvironment) ? useEnvironment : environmentId)); + config.setConfig(ElementUtil.getEnvironmentConfig(StringUtils.isNotEmpty(useEnvironment) ? useEnvironment : environmentId, this.getProjectId(), this.isMockEnvironment())); } // 数据兼容处理 @@ -205,7 +213,9 @@ public class MsJDBCSampler extends MsTestElement { if (bloBs != null) { this.setName(bloBs.getName()); this.setProjectId(bloBs.getProjectId()); - proxy = mapper.readValue(bloBs.getRequest(), new TypeReference() { + JSONObject element = JSON.parseObject(bloBs.getRequest()); + ElementUtil.dataFormatting(element); + proxy = mapper.readValue(element.toJSONString(), new TypeReference() { }); } } else { @@ -272,7 +282,7 @@ public class MsJDBCSampler extends MsTestElement { JDBCSampler sampler = new JDBCSampler(); sampler.setEnabled(this.isEnable()); sampler.setName(this.getName()); - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { sampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } @@ -280,9 +290,9 @@ public class MsJDBCSampler extends MsTestElement { sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); sampler.setProperty("MS-ID", this.getId()); String indexPath = this.getIndex(); - sampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + this.getFullIndexPath(this.getParent(), indexPath)); + sampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + ElementUtil.getFullIndexPath(this.getParent(), indexPath)); List id_names = new LinkedList<>(); - this.getScenarioSet(this, id_names); + ElementUtil.getScenarioSet(this, id_names); sampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); // request.getDataSource() 是ID,需要转换为Name diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java index 84c2b53bd5..df67715e5a 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java @@ -1,6 +1,7 @@ package io.metersphere.api.dto.definition.request.sampler; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.core.type.TypeReference; @@ -8,7 +9,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.dto.automation.EsbDataStruct; import io.metersphere.api.dto.automation.TcpTreeTableDataStruct; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor; import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; @@ -23,6 +24,8 @@ import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; import io.metersphere.jmeter.utils.ScriptEngineUtils; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -52,6 +55,8 @@ import java.util.regex.Pattern; public class MsTCPSampler extends MsTestElement { @JSONField(ordinal = 20) private String type = "TCPSampler"; + private String clazzName = "io.metersphere.api.dto.definition.request.sampler.MsTCPSampler"; + @JSONField(ordinal = 21) private String classname = ""; @JSONField(ordinal = 22) @@ -99,6 +104,9 @@ public class MsTCPSampler extends MsTestElement { @JSONField(ordinal = 44) private String rawDataStruct; + @JSONField(ordinal = 45) + private boolean customizeReq; + private MsJSR223PreProcessor preProcessor; private MsJSR223PostProcessor postProcessor; @@ -109,7 +117,8 @@ public class MsTCPSampler extends MsTestElement { private List backEsbDataStruct; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; @@ -120,14 +129,14 @@ public class MsTCPSampler extends MsTestElement { if (config.getConfig() == null) { // 单独接口执行 this.setProjectId(config.getProjectId()); - config.setConfig(getEnvironmentConfig(useEnvironment)); + config.setConfig(ElementUtil.getEnvironmentConfig(useEnvironment, this.getProjectId(), this.isMockEnvironment())); } if (config.getConfig() != null) { parseEnvironment(config.getConfig().get(this.projectId)); } // 添加环境中的公共变量 - Arguments arguments = this.addArguments(config); + Arguments arguments = ElementUtil.addArguments(config, this.getProjectId(), this.getName()); if (arguments != null) { tree.add(arguments); } @@ -180,7 +189,9 @@ public class MsTCPSampler extends MsTestElement { if (bloBs != null) { this.setName(bloBs.getName()); this.setProjectId(bloBs.getProjectId()); - proxy = mapper.readValue(bloBs.getRequest(), new TypeReference() { + JSONObject element = JSON.parseObject(bloBs.getRequest()); + ElementUtil.dataFormatting(element); + proxy = mapper.readValue(element.toJSONString(), new TypeReference() { }); } } else { @@ -229,15 +240,15 @@ public class MsTCPSampler extends MsTestElement { TCPSampler tcpSampler = new TCPSampler(); tcpSampler.setEnabled(this.isEnable()); tcpSampler.setName(this.getName()); - String name = this.getParentName(this.getParent()); + String name = ElementUtil.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { tcpSampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } tcpSampler.setProperty("MS-ID", this.getId()); String indexPath = this.getIndex(); - tcpSampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + this.getFullIndexPath(this.getParent(), indexPath)); + tcpSampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + ElementUtil.getFullIndexPath(this.getParent(), indexPath)); List id_names = new LinkedList<>(); - this.getScenarioSet(this, id_names); + ElementUtil.getScenarioSet(this, id_names); tcpSampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); tcpSampler.setProperty(TestElement.TEST_CLASS, TCPSampler.class.getName()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/timer/MsConstantTimer.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/timer/MsConstantTimer.java index ad481db7f5..20bb6b90e3 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/timer/MsConstantTimer.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/timer/MsConstantTimer.java @@ -2,8 +2,9 @@ package io.metersphere.api.dto.definition.request.timer; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -19,13 +20,16 @@ import java.util.List; @JSONType(typeName = "ConstantTimer") public class MsConstantTimer extends MsTestElement { private String type = "ConstantTimer"; + private String clazzName = "io.metersphere.api.dto.definition.request.timer.MsConstantTimer"; + @JSONField(ordinal = 20) private String id; @JSONField(ordinal = 21) private String delay; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/unknown/MsJmeterElement.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/unknown/MsJmeterElement.java index e6870ce3b1..1630609536 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/unknown/MsJmeterElement.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/unknown/MsJmeterElement.java @@ -1,13 +1,14 @@ package io.metersphere.api.dto.definition.request.unknown; import com.alibaba.fastjson.annotation.JSONType; -import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; import io.metersphere.api.dto.scenario.request.BodyFile; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.FileUtils; import io.metersphere.commons.utils.LogUtil; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -33,12 +34,15 @@ import java.util.stream.Collectors; @JSONType(typeName = "JmeterElement") public class MsJmeterElement extends MsTestElement { private String type = "JmeterElement"; + private String clazzName = "io.metersphere.api.dto.definition.request.unknown.MsJmeterElement"; + private String elementType; private String jmeterElement; @Override - public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { try { + ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 if (!config.isOperating() && !this.isEnable()) { return; diff --git a/backend/src/main/java/io/metersphere/api/parse/HarScenarioAbstractParser.java b/backend/src/main/java/io/metersphere/api/parse/HarScenarioAbstractParser.java index a34c804f6c..f96050fb41 100644 --- a/backend/src/main/java/io/metersphere/api/parse/HarScenarioAbstractParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/HarScenarioAbstractParser.java @@ -3,7 +3,7 @@ package io.metersphere.api.parse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.definition.parse.har.model.*; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.parse.postman.PostmanEvent; diff --git a/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java b/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java index bde77056ee..4a48319285 100644 --- a/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java @@ -2,7 +2,7 @@ package io.metersphere.api.parse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.parse.postman.*; diff --git a/backend/src/main/java/io/metersphere/api/parse/old/PostmanParser.java b/backend/src/main/java/io/metersphere/api/parse/old/PostmanParser.java index 56be3545dc..437380022e 100644 --- a/backend/src/main/java/io/metersphere/api/parse/old/PostmanParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/old/PostmanParser.java @@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.configurations.MsHeaderManager; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.parse.ApiImport; diff --git a/backend/src/main/java/io/metersphere/api/parse/old/Swagger2Parser.java b/backend/src/main/java/io/metersphere/api/parse/old/Swagger2Parser.java index 57512fca3f..f0e3cbd06b 100644 --- a/backend/src/main/java/io/metersphere/api/parse/old/Swagger2Parser.java +++ b/backend/src/main/java/io/metersphere/api/parse/old/Swagger2Parser.java @@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.configurations.MsHeaderManager; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.parse.ApiImport; diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index 6eb9e27a7e..df87a6c37c 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -42,6 +42,7 @@ import io.metersphere.log.utils.ReflexObjectUtil; import io.metersphere.log.vo.DetailColumn; import io.metersphere.log.vo.OperatingLogDetails; import io.metersphere.log.vo.api.AutomationReference; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.service.ScheduleService; import io.metersphere.service.SystemParameterService; import io.metersphere.track.dto.TestPlanDTO; @@ -601,6 +602,7 @@ public class ApiAutomationService { JSONObject element = JSON.parseObject(definition); try { if (element != null) { + ElementUtil.dataFormatting(element); return objectMapper.readValue(element.getString("hashTree"), new TypeReference>() { }); } @@ -611,9 +613,7 @@ public class ApiAutomationService { } public ScenarioEnv getApiScenarioEnv(String definition) { - ObjectMapper mapper = new ObjectMapper(); ScenarioEnv env = new ScenarioEnv(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); List hashTree = getScenarioHashTree(definition); for (int i = 0; i < hashTree.size(); i++) { MsTestElement tr = hashTree.get(i); @@ -727,6 +727,7 @@ public class ApiAutomationService { env.getProjectIds().add(apiScenario.getProjectId()); String scenarioDefinition = apiScenario.getScenarioDefinition(); JSONObject element1 = JSON.parseObject(scenarioDefinition); + ElementUtil.dataFormatting(element1); LinkedList hashTree1 = mapper.readValue(element1.getString("hashTree"), new TypeReference>() { }); tr.setHashTree(hashTree1); @@ -738,7 +739,7 @@ public class ApiAutomationService { // 校验是否是全路径 MsHTTPSamplerProxy httpSamplerProxy = (MsHTTPSamplerProxy) tr; if (httpSamplerProxy.isEnable()) { - if (StringUtils.isBlank(httpSamplerProxy.getUrl()) || !tr.isURL(httpSamplerProxy.getUrl())) { + if (StringUtils.isBlank(httpSamplerProxy.getUrl()) || !ElementUtil.isURL(httpSamplerProxy.getUrl())) { env.setFullUrl(false); env.getProjectIds().add(httpSamplerProxy.getProjectId()); } @@ -826,6 +827,8 @@ public class ApiAutomationService { mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); try { JSONObject element = JSON.parseObject(scenarioDefinition); + ElementUtil.dataFormatting(element); + // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { LinkedList elements = mapper.readValue(element.getString("hashTree"), @@ -1207,7 +1210,7 @@ public class ApiAutomationService { ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class); for (ApiScenarioWithBLOBs item : apiScenarios) { if (item.getStepTotal() == null || item.getStepTotal() == 0) { - // 只有一个场景且没有测试步骤,则提示 + // 只有 一个场景且没有测试步骤,则提示 if (apiScenarios.size() == 1) { MSException.throwException((item.getName() + "," + Translator.get("automation_exec_info"))); } @@ -1227,6 +1230,9 @@ public class ApiAutomationService { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); JSONObject element = JSON.parseObject(item.getScenarioDefinition()); + // 历史数据处理 + ElementUtil.dataFormatting(element.getJSONArray("hashTree")); + MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class); group.setOnSampleError(scenario.getOnSampleError()); this.preduceMsScenario(scenario); @@ -1307,8 +1313,6 @@ public class ApiAutomationService { } private boolean checkScenarioEnv(ApiScenarioWithBLOBs apiScenarioWithBLOBs, TestPlanApiScenario testPlanApiScenarios) { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); String definition = apiScenarioWithBLOBs.getScenarioDefinition(); MsScenario scenario = JSONObject.parseObject(definition, MsScenario.class); boolean isEnv = true; diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index 88ebd7ccb5..e2dd1fdd56 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -10,7 +10,7 @@ import io.metersphere.api.dto.DeleteCheckResult; import io.metersphere.api.dto.JmxInfoDTO; import io.metersphere.api.dto.datacount.ApiDataCountResult; import io.metersphere.api.dto.definition.*; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.MsThreadGroup; import io.metersphere.api.dto.definition.request.ParameterConfig; @@ -29,6 +29,7 @@ import io.metersphere.log.utils.ReflexObjectUtil; import io.metersphere.log.vo.DetailColumn; import io.metersphere.log.vo.OperatingLogDetails; import io.metersphere.log.vo.api.DefinitionReference; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.service.FileService; import io.metersphere.service.QuotaService; import io.metersphere.service.UserService; @@ -551,8 +552,6 @@ public class ApiTestCaseService { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); ApiTestCaseMapper batchMapper = sqlSession.getMapper(ApiTestCaseMapper.class); - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); bloBs.forEach(apiTestCase -> { JSONObject req = JSON.parseObject(apiTestCase.getRequest()); req.put("useEnvironment", request.getEnvId()); @@ -578,6 +577,8 @@ public class ApiTestCaseService { MsHTTPSamplerProxy req = JSON.parseObject(apiTestCase.getRequest(), MsHTTPSamplerProxy.class); try { JSONObject element = JSON.parseObject(apiTestCase.getRequest()); + ElementUtil.dataFormatting(element); + if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { LinkedList elements = mapper.readValue(element.getString("hashTree"), new TypeReference>() { }); @@ -717,7 +718,10 @@ public class ApiTestCaseService { public HashTree generateHashTree(RunCaseRequest request, ApiTestCaseWithBLOBs testCaseWithBLOBs) throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - MsTestElement element = mapper.readValue(testCaseWithBLOBs.getRequest(), new TypeReference() { + JSONObject elementObj = JSON.parseObject(testCaseWithBLOBs.getRequest()); + ElementUtil.dataFormatting(elementObj); + + MsTestElement element = mapper.readValue(elementObj.toJSONString(), new TypeReference() { }); element.setProjectId(testCaseWithBLOBs.getProjectId()); if (StringUtils.isBlank(request.getEnvironmentId())) { diff --git a/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java b/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java index e6373d7404..b71034549d 100644 --- a/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java +++ b/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java @@ -6,7 +6,7 @@ import io.metersphere.api.dto.automation.EsbDataStruct; import io.metersphere.api.dto.automation.SaveApiScenarioRequest; import io.metersphere.api.dto.automation.parse.EsbDataParser; import io.metersphere.api.dto.definition.*; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; import io.metersphere.api.dto.scenario.KeyValue; diff --git a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java index 948b6d932a..6638aeab5d 100644 --- a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java +++ b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java @@ -8,7 +8,7 @@ import io.metersphere.api.dto.SaveHistoricalDataUpgrade; import io.metersphere.api.dto.automation.ScenarioStatus; import io.metersphere.api.dto.datacount.ApiMethodUrlDTO; import io.metersphere.api.dto.definition.request.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.assertions.MsAssertionDuration; import io.metersphere.api.dto.definition.request.assertions.MsAssertions; import io.metersphere.api.dto.definition.request.controller.MsIfController; diff --git a/backend/src/main/java/io/metersphere/api/service/TcpApiParamService.java b/backend/src/main/java/io/metersphere/api/service/TcpApiParamService.java index a7d1a5be48..8236ffaf69 100644 --- a/backend/src/main/java/io/metersphere/api/service/TcpApiParamService.java +++ b/backend/src/main/java/io/metersphere/api/service/TcpApiParamService.java @@ -3,7 +3,7 @@ package io.metersphere.api.service; import io.metersphere.api.dto.automation.TcpTreeTableDataStruct; import io.metersphere.api.dto.automation.parse.TcpTreeTableDataParser; import io.metersphere.api.dto.definition.SaveApiDefinitionRequest; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; diff --git a/backend/src/main/java/io/metersphere/base/domain/Plugin.java b/backend/src/main/java/io/metersphere/base/domain/Plugin.java new file mode 100644 index 0000000000..306c4318ce --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/domain/Plugin.java @@ -0,0 +1,30 @@ +package io.metersphere.base.domain; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class Plugin implements Serializable { + private String id; + + private String name; + + private String pluginId; + + private String clazzName; + + private String sourcePath; + + private String sourceName; + + private String execEntry; + + private Long createTime; + + private Long updateTime; + + private String createUserId; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/PluginExample.java b/backend/src/main/java/io/metersphere/base/domain/PluginExample.java new file mode 100644 index 0000000000..14bffb2d43 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/domain/PluginExample.java @@ -0,0 +1,880 @@ +package io.metersphere.base.domain; + +import java.util.ArrayList; +import java.util.List; + +public class PluginExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public PluginExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andIdIsNull() { + addCriterion("id is null"); + return (Criteria) this; + } + + public Criteria andIdIsNotNull() { + addCriterion("id is not null"); + return (Criteria) this; + } + + public Criteria andIdEqualTo(String value) { + addCriterion("id =", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotEqualTo(String value) { + addCriterion("id <>", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThan(String value) { + addCriterion("id >", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThanOrEqualTo(String value) { + addCriterion("id >=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThan(String value) { + addCriterion("id <", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThanOrEqualTo(String value) { + addCriterion("id <=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLike(String value) { + addCriterion("id like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotLike(String value) { + addCriterion("id not like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdIn(List values) { + addCriterion("id in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdNotIn(List values) { + addCriterion("id not in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdBetween(String value1, String value2) { + addCriterion("id between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andIdNotBetween(String value1, String value2) { + addCriterion("id not between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andNameIsNull() { + addCriterion("`name` is null"); + return (Criteria) this; + } + + public Criteria andNameIsNotNull() { + addCriterion("`name` is not null"); + return (Criteria) this; + } + + public Criteria andNameEqualTo(String value) { + addCriterion("`name` =", value, "name"); + return (Criteria) this; + } + + public Criteria andNameNotEqualTo(String value) { + addCriterion("`name` <>", value, "name"); + return (Criteria) this; + } + + public Criteria andNameGreaterThan(String value) { + addCriterion("`name` >", value, "name"); + return (Criteria) this; + } + + public Criteria andNameGreaterThanOrEqualTo(String value) { + addCriterion("`name` >=", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLessThan(String value) { + addCriterion("`name` <", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLessThanOrEqualTo(String value) { + addCriterion("`name` <=", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLike(String value) { + addCriterion("`name` like", value, "name"); + return (Criteria) this; + } + + public Criteria andNameNotLike(String value) { + addCriterion("`name` not like", value, "name"); + return (Criteria) this; + } + + public Criteria andNameIn(List values) { + addCriterion("`name` in", values, "name"); + return (Criteria) this; + } + + public Criteria andNameNotIn(List values) { + addCriterion("`name` not in", values, "name"); + return (Criteria) this; + } + + public Criteria andNameBetween(String value1, String value2) { + addCriterion("`name` between", value1, value2, "name"); + return (Criteria) this; + } + + public Criteria andNameNotBetween(String value1, String value2) { + addCriterion("`name` not between", value1, value2, "name"); + return (Criteria) this; + } + + public Criteria andPluginIdIsNull() { + addCriterion("plugin_id is null"); + return (Criteria) this; + } + + public Criteria andPluginIdIsNotNull() { + addCriterion("plugin_id is not null"); + return (Criteria) this; + } + + public Criteria andPluginIdEqualTo(String value) { + addCriterion("plugin_id =", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdNotEqualTo(String value) { + addCriterion("plugin_id <>", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdGreaterThan(String value) { + addCriterion("plugin_id >", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdGreaterThanOrEqualTo(String value) { + addCriterion("plugin_id >=", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdLessThan(String value) { + addCriterion("plugin_id <", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdLessThanOrEqualTo(String value) { + addCriterion("plugin_id <=", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdLike(String value) { + addCriterion("plugin_id like", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdNotLike(String value) { + addCriterion("plugin_id not like", value, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdIn(List values) { + addCriterion("plugin_id in", values, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdNotIn(List values) { + addCriterion("plugin_id not in", values, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdBetween(String value1, String value2) { + addCriterion("plugin_id between", value1, value2, "pluginId"); + return (Criteria) this; + } + + public Criteria andPluginIdNotBetween(String value1, String value2) { + addCriterion("plugin_id not between", value1, value2, "pluginId"); + return (Criteria) this; + } + + public Criteria andClazzNameIsNull() { + addCriterion("clazz_name is null"); + return (Criteria) this; + } + + public Criteria andClazzNameIsNotNull() { + addCriterion("clazz_name is not null"); + return (Criteria) this; + } + + public Criteria andClazzNameEqualTo(String value) { + addCriterion("clazz_name =", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameNotEqualTo(String value) { + addCriterion("clazz_name <>", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameGreaterThan(String value) { + addCriterion("clazz_name >", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameGreaterThanOrEqualTo(String value) { + addCriterion("clazz_name >=", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameLessThan(String value) { + addCriterion("clazz_name <", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameLessThanOrEqualTo(String value) { + addCriterion("clazz_name <=", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameLike(String value) { + addCriterion("clazz_name like", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameNotLike(String value) { + addCriterion("clazz_name not like", value, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameIn(List values) { + addCriterion("clazz_name in", values, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameNotIn(List values) { + addCriterion("clazz_name not in", values, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameBetween(String value1, String value2) { + addCriterion("clazz_name between", value1, value2, "clazzName"); + return (Criteria) this; + } + + public Criteria andClazzNameNotBetween(String value1, String value2) { + addCriterion("clazz_name not between", value1, value2, "clazzName"); + return (Criteria) this; + } + + public Criteria andSourcePathIsNull() { + addCriterion("source_path is null"); + return (Criteria) this; + } + + public Criteria andSourcePathIsNotNull() { + addCriterion("source_path is not null"); + return (Criteria) this; + } + + public Criteria andSourcePathEqualTo(String value) { + addCriterion("source_path =", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathNotEqualTo(String value) { + addCriterion("source_path <>", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathGreaterThan(String value) { + addCriterion("source_path >", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathGreaterThanOrEqualTo(String value) { + addCriterion("source_path >=", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathLessThan(String value) { + addCriterion("source_path <", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathLessThanOrEqualTo(String value) { + addCriterion("source_path <=", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathLike(String value) { + addCriterion("source_path like", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathNotLike(String value) { + addCriterion("source_path not like", value, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathIn(List values) { + addCriterion("source_path in", values, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathNotIn(List values) { + addCriterion("source_path not in", values, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathBetween(String value1, String value2) { + addCriterion("source_path between", value1, value2, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourcePathNotBetween(String value1, String value2) { + addCriterion("source_path not between", value1, value2, "sourcePath"); + return (Criteria) this; + } + + public Criteria andSourceNameIsNull() { + addCriterion("source_name is null"); + return (Criteria) this; + } + + public Criteria andSourceNameIsNotNull() { + addCriterion("source_name is not null"); + return (Criteria) this; + } + + public Criteria andSourceNameEqualTo(String value) { + addCriterion("source_name =", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameNotEqualTo(String value) { + addCriterion("source_name <>", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameGreaterThan(String value) { + addCriterion("source_name >", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameGreaterThanOrEqualTo(String value) { + addCriterion("source_name >=", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameLessThan(String value) { + addCriterion("source_name <", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameLessThanOrEqualTo(String value) { + addCriterion("source_name <=", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameLike(String value) { + addCriterion("source_name like", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameNotLike(String value) { + addCriterion("source_name not like", value, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameIn(List values) { + addCriterion("source_name in", values, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameNotIn(List values) { + addCriterion("source_name not in", values, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameBetween(String value1, String value2) { + addCriterion("source_name between", value1, value2, "sourceName"); + return (Criteria) this; + } + + public Criteria andSourceNameNotBetween(String value1, String value2) { + addCriterion("source_name not between", value1, value2, "sourceName"); + return (Criteria) this; + } + + public Criteria andExecEntryIsNull() { + addCriterion("exec_entry is null"); + return (Criteria) this; + } + + public Criteria andExecEntryIsNotNull() { + addCriterion("exec_entry is not null"); + return (Criteria) this; + } + + public Criteria andExecEntryEqualTo(String value) { + addCriterion("exec_entry =", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryNotEqualTo(String value) { + addCriterion("exec_entry <>", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryGreaterThan(String value) { + addCriterion("exec_entry >", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryGreaterThanOrEqualTo(String value) { + addCriterion("exec_entry >=", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryLessThan(String value) { + addCriterion("exec_entry <", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryLessThanOrEqualTo(String value) { + addCriterion("exec_entry <=", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryLike(String value) { + addCriterion("exec_entry like", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryNotLike(String value) { + addCriterion("exec_entry not like", value, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryIn(List values) { + addCriterion("exec_entry in", values, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryNotIn(List values) { + addCriterion("exec_entry not in", values, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryBetween(String value1, String value2) { + addCriterion("exec_entry between", value1, value2, "execEntry"); + return (Criteria) this; + } + + public Criteria andExecEntryNotBetween(String value1, String value2) { + addCriterion("exec_entry not between", value1, value2, "execEntry"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNull() { + addCriterion("create_time is null"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNotNull() { + addCriterion("create_time is not null"); + return (Criteria) this; + } + + public Criteria andCreateTimeEqualTo(Long value) { + addCriterion("create_time =", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotEqualTo(Long value) { + addCriterion("create_time <>", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThan(Long value) { + addCriterion("create_time >", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) { + addCriterion("create_time >=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThan(Long value) { + addCriterion("create_time <", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThanOrEqualTo(Long value) { + addCriterion("create_time <=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeIn(List values) { + addCriterion("create_time in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotIn(List values) { + addCriterion("create_time not in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeBetween(Long value1, Long value2) { + addCriterion("create_time between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotBetween(Long value1, Long value2) { + addCriterion("create_time not between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIsNull() { + addCriterion("update_time is null"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIsNotNull() { + addCriterion("update_time is not null"); + return (Criteria) this; + } + + public Criteria andUpdateTimeEqualTo(Long value) { + addCriterion("update_time =", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotEqualTo(Long value) { + addCriterion("update_time <>", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeGreaterThan(Long value) { + addCriterion("update_time >", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeGreaterThanOrEqualTo(Long value) { + addCriterion("update_time >=", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeLessThan(Long value) { + addCriterion("update_time <", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeLessThanOrEqualTo(Long value) { + addCriterion("update_time <=", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIn(List values) { + addCriterion("update_time in", values, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotIn(List values) { + addCriterion("update_time not in", values, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeBetween(Long value1, Long value2) { + addCriterion("update_time between", value1, value2, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotBetween(Long value1, Long value2) { + addCriterion("update_time not between", value1, value2, "updateTime"); + return (Criteria) this; + } + + public Criteria andCreateUserIdIsNull() { + addCriterion("create_user_id is null"); + return (Criteria) this; + } + + public Criteria andCreateUserIdIsNotNull() { + addCriterion("create_user_id is not null"); + return (Criteria) this; + } + + public Criteria andCreateUserIdEqualTo(String value) { + addCriterion("create_user_id =", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdNotEqualTo(String value) { + addCriterion("create_user_id <>", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdGreaterThan(String value) { + addCriterion("create_user_id >", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdGreaterThanOrEqualTo(String value) { + addCriterion("create_user_id >=", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdLessThan(String value) { + addCriterion("create_user_id <", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdLessThanOrEqualTo(String value) { + addCriterion("create_user_id <=", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdLike(String value) { + addCriterion("create_user_id like", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdNotLike(String value) { + addCriterion("create_user_id not like", value, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdIn(List values) { + addCriterion("create_user_id in", values, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdNotIn(List values) { + addCriterion("create_user_id not in", values, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdBetween(String value1, String value2) { + addCriterion("create_user_id between", value1, value2, "createUserId"); + return (Criteria) this; + } + + public Criteria andCreateUserIdNotBetween(String value1, String value2) { + addCriterion("create_user_id not between", value1, value2, "createUserId"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/PluginWithBLOBs.java b/backend/src/main/java/io/metersphere/base/domain/PluginWithBLOBs.java new file mode 100644 index 0000000000..889cacb428 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/domain/PluginWithBLOBs.java @@ -0,0 +1,18 @@ +package io.metersphere.base.domain; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.io.Serializable; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PluginWithBLOBs extends Plugin implements Serializable { + private String formOption; + + private String formScript; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/PluginMapper.java b/backend/src/main/java/io/metersphere/base/mapper/PluginMapper.java new file mode 100644 index 0000000000..7ac28d6cf3 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/PluginMapper.java @@ -0,0 +1,37 @@ +package io.metersphere.base.mapper; + +import io.metersphere.base.domain.Plugin; +import io.metersphere.base.domain.PluginExample; +import io.metersphere.base.domain.PluginWithBLOBs; +import java.util.List; +import org.apache.ibatis.annotations.Param; + +public interface PluginMapper { + long countByExample(PluginExample example); + + int deleteByExample(PluginExample example); + + int deleteByPrimaryKey(String id); + + int insert(PluginWithBLOBs record); + + int insertSelective(PluginWithBLOBs record); + + List selectByExampleWithBLOBs(PluginExample example); + + List selectByExample(PluginExample example); + + PluginWithBLOBs selectByPrimaryKey(String id); + + int updateByExampleSelective(@Param("record") PluginWithBLOBs record, @Param("example") PluginExample example); + + int updateByExampleWithBLOBs(@Param("record") PluginWithBLOBs record, @Param("example") PluginExample example); + + int updateByExample(@Param("record") Plugin record, @Param("example") PluginExample example); + + int updateByPrimaryKeySelective(PluginWithBLOBs record); + + int updateByPrimaryKeyWithBLOBs(PluginWithBLOBs record); + + int updateByPrimaryKey(Plugin record); +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/PluginMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/PluginMapper.xml new file mode 100644 index 0000000000..27e3caa052 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/PluginMapper.xml @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + id, `name`, plugin_id, clazz_name, source_path, source_name, exec_entry, create_time, + update_time, create_user_id + + + form_option, form_script + + + + + + delete from plugin + where id = #{id,jdbcType=VARCHAR} + + + delete from plugin + + + + + + insert into plugin (id, `name`, plugin_id, + clazz_name, source_path, source_name, + exec_entry, create_time, update_time, + create_user_id, form_option, form_script + ) + values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{pluginId,jdbcType=VARCHAR}, + #{clazzName,jdbcType=VARCHAR}, #{sourcePath,jdbcType=VARCHAR}, #{sourceName,jdbcType=VARCHAR}, + #{execEntry,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, + #{createUserId,jdbcType=VARCHAR}, #{formOption,jdbcType=LONGVARCHAR}, #{formScript,jdbcType=LONGVARCHAR} + ) + + + insert into plugin + + + id, + + + `name`, + + + plugin_id, + + + clazz_name, + + + source_path, + + + source_name, + + + exec_entry, + + + create_time, + + + update_time, + + + create_user_id, + + + form_option, + + + form_script, + + + + + #{id,jdbcType=VARCHAR}, + + + #{name,jdbcType=VARCHAR}, + + + #{pluginId,jdbcType=VARCHAR}, + + + #{clazzName,jdbcType=VARCHAR}, + + + #{sourcePath,jdbcType=VARCHAR}, + + + #{sourceName,jdbcType=VARCHAR}, + + + #{execEntry,jdbcType=VARCHAR}, + + + #{createTime,jdbcType=BIGINT}, + + + #{updateTime,jdbcType=BIGINT}, + + + #{createUserId,jdbcType=VARCHAR}, + + + #{formOption,jdbcType=LONGVARCHAR}, + + + #{formScript,jdbcType=LONGVARCHAR}, + + + + + + update plugin + + + id = #{record.id,jdbcType=VARCHAR}, + + + `name` = #{record.name,jdbcType=VARCHAR}, + + + plugin_id = #{record.pluginId,jdbcType=VARCHAR}, + + + clazz_name = #{record.clazzName,jdbcType=VARCHAR}, + + + source_path = #{record.sourcePath,jdbcType=VARCHAR}, + + + source_name = #{record.sourceName,jdbcType=VARCHAR}, + + + exec_entry = #{record.execEntry,jdbcType=VARCHAR}, + + + create_time = #{record.createTime,jdbcType=BIGINT}, + + + update_time = #{record.updateTime,jdbcType=BIGINT}, + + + create_user_id = #{record.createUserId,jdbcType=VARCHAR}, + + + form_option = #{record.formOption,jdbcType=LONGVARCHAR}, + + + form_script = #{record.formScript,jdbcType=LONGVARCHAR}, + + + + + + + + update plugin + set id = #{record.id,jdbcType=VARCHAR}, + `name` = #{record.name,jdbcType=VARCHAR}, + plugin_id = #{record.pluginId,jdbcType=VARCHAR}, + clazz_name = #{record.clazzName,jdbcType=VARCHAR}, + source_path = #{record.sourcePath,jdbcType=VARCHAR}, + source_name = #{record.sourceName,jdbcType=VARCHAR}, + exec_entry = #{record.execEntry,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + update_time = #{record.updateTime,jdbcType=BIGINT}, + create_user_id = #{record.createUserId,jdbcType=VARCHAR}, + form_option = #{record.formOption,jdbcType=LONGVARCHAR}, + form_script = #{record.formScript,jdbcType=LONGVARCHAR} + + + + + + update plugin + set id = #{record.id,jdbcType=VARCHAR}, + `name` = #{record.name,jdbcType=VARCHAR}, + plugin_id = #{record.pluginId,jdbcType=VARCHAR}, + clazz_name = #{record.clazzName,jdbcType=VARCHAR}, + source_path = #{record.sourcePath,jdbcType=VARCHAR}, + source_name = #{record.sourceName,jdbcType=VARCHAR}, + exec_entry = #{record.execEntry,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + update_time = #{record.updateTime,jdbcType=BIGINT}, + create_user_id = #{record.createUserId,jdbcType=VARCHAR} + + + + + + update plugin + + + `name` = #{name,jdbcType=VARCHAR}, + + + plugin_id = #{pluginId,jdbcType=VARCHAR}, + + + clazz_name = #{clazzName,jdbcType=VARCHAR}, + + + source_path = #{sourcePath,jdbcType=VARCHAR}, + + + source_name = #{sourceName,jdbcType=VARCHAR}, + + + exec_entry = #{execEntry,jdbcType=VARCHAR}, + + + create_time = #{createTime,jdbcType=BIGINT}, + + + update_time = #{updateTime,jdbcType=BIGINT}, + + + create_user_id = #{createUserId,jdbcType=VARCHAR}, + + + form_option = #{formOption,jdbcType=LONGVARCHAR}, + + + form_script = #{formScript,jdbcType=LONGVARCHAR}, + + + where id = #{id,jdbcType=VARCHAR} + + + update plugin + set `name` = #{name,jdbcType=VARCHAR}, + plugin_id = #{pluginId,jdbcType=VARCHAR}, + clazz_name = #{clazzName,jdbcType=VARCHAR}, + source_path = #{sourcePath,jdbcType=VARCHAR}, + source_name = #{sourceName,jdbcType=VARCHAR}, + exec_entry = #{execEntry,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + update_time = #{updateTime,jdbcType=BIGINT}, + create_user_id = #{createUserId,jdbcType=VARCHAR}, + form_option = #{formOption,jdbcType=LONGVARCHAR}, + form_script = #{formScript,jdbcType=LONGVARCHAR} + where id = #{id,jdbcType=VARCHAR} + + + update plugin + set `name` = #{name,jdbcType=VARCHAR}, + plugin_id = #{pluginId,jdbcType=VARCHAR}, + clazz_name = #{clazzName,jdbcType=VARCHAR}, + source_path = #{sourcePath,jdbcType=VARCHAR}, + source_name = #{sourceName,jdbcType=VARCHAR}, + exec_entry = #{execEntry,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + update_time = #{updateTime,jdbcType=BIGINT}, + create_user_id = #{createUserId,jdbcType=VARCHAR} + where id = #{id,jdbcType=VARCHAR} + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java b/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java index 685a083300..c0d1e52b6a 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/FileUtils.java @@ -54,6 +54,30 @@ public class FileUtils { } } + public static String create(String id, MultipartFile item) { + String filePath = BODY_FILE_DIR + "/plugin"; + if (item != null) { + File testDir = new File(filePath); + if (!testDir.exists()) { + testDir.mkdirs(); + } + File file = new File(filePath + "/" + id + "_" + item.getOriginalFilename()); + try (InputStream in = item.getInputStream(); OutputStream out = new FileOutputStream(file)) { + file.createNewFile(); + final int MAX = 4096; + byte[] buf = new byte[MAX]; + for (int bytesRead = in.read(buf, 0, MAX); bytesRead != -1; bytesRead = in.read(buf, 0, MAX)) { + out.write(buf, 0, bytesRead); + } + } catch (IOException e) { + LogUtil.error(e); + MSException.throwException(Translator.get("upload_fail")); + } + return file.getPath(); + } + return null; + } + public static void createBodyFiles(String requestId, List bodyFiles) { if (CollectionUtils.isNotEmpty(bodyFiles) && StringUtils.isNotBlank(requestId)) { String path = BODY_FILE_DIR + "/" + requestId; @@ -158,7 +182,6 @@ public class FileUtils { } - /** * 获取当前jmx 涉及到的文件 * diff --git a/backend/src/main/java/io/metersphere/commons/utils/LogUtil.java b/backend/src/main/java/io/metersphere/commons/utils/LogUtil.java index 3b2fba94a6..3bd5136aa9 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/LogUtil.java +++ b/backend/src/main/java/io/metersphere/commons/utils/LogUtil.java @@ -55,6 +55,7 @@ public class LogUtil { Logger logger = LogUtil.getLogger(); if (logger != null && logger.isInfoEnabled()) { logger.info(LogUtil.getMsg(msg)); + System.out.println(msg); } } diff --git a/backend/src/main/java/io/metersphere/commons/utils/ShiroUtils.java b/backend/src/main/java/io/metersphere/commons/utils/ShiroUtils.java index 6c7539101d..1e46704f07 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/ShiroUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/ShiroUtils.java @@ -69,6 +69,8 @@ public class ShiroUtils { filterChainDefinitionMap.put("/mock/**", "anon"); filterChainDefinitionMap.put("/ws/**", "anon"); + filterChainDefinitionMap.put("/plugin/**", "anon"); + } public static void ignoreCsrfFilter(Map filterChainDefinitionMap) { diff --git a/backend/src/main/java/io/metersphere/controller/PluginController.java b/backend/src/main/java/io/metersphere/controller/PluginController.java new file mode 100644 index 0000000000..f223ba0a13 --- /dev/null +++ b/backend/src/main/java/io/metersphere/controller/PluginController.java @@ -0,0 +1,48 @@ +package io.metersphere.controller; + +import io.metersphere.base.domain.Plugin; +import io.metersphere.commons.exception.MSException; +import io.metersphere.controller.request.PluginRequest; +import io.metersphere.service.PluginService; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.util.List; + +@RestController +@RequestMapping(value = "/plugin") +public class PluginController { + + @Resource + private PluginService pluginService; + + @PostMapping("/add") + public String create(@RequestPart(value = "file", required = false) MultipartFile file) { + if (file == null) { + MSException.throwException("上传文件/执行入口为空"); + } + return pluginService.editPlugin(file); + } + + @GetMapping("/list") + public List list() { + return pluginService.list(); + } + + @GetMapping("/get/{id}") + public Plugin get(@PathVariable String id) { + return pluginService.get(id); + } + + @GetMapping("/delete/{id}") + public String delete(@PathVariable String id) { + return pluginService.delete(id); + } + + @PostMapping(value = "/customMethod") + public Object customMethod(@RequestBody PluginRequest request) { + return pluginService.customMethod(request); + } + +} diff --git a/backend/src/main/java/io/metersphere/controller/request/PluginRequest.java b/backend/src/main/java/io/metersphere/controller/request/PluginRequest.java new file mode 100644 index 0000000000..ff0f692e67 --- /dev/null +++ b/backend/src/main/java/io/metersphere/controller/request/PluginRequest.java @@ -0,0 +1,9 @@ +package io.metersphere.controller.request; + +import lombok.Data; + +@Data +public class PluginRequest { + private String entry; + private String request; +} diff --git a/backend/src/main/java/io/metersphere/controller/request/PluginResourceDTO.java b/backend/src/main/java/io/metersphere/controller/request/PluginResourceDTO.java new file mode 100644 index 0000000000..d5ecbe586a --- /dev/null +++ b/backend/src/main/java/io/metersphere/controller/request/PluginResourceDTO.java @@ -0,0 +1,9 @@ +package io.metersphere.controller.request; + +import io.metersphere.plugin.core.ui.PluginResource; +import lombok.Data; + +@Data +public class PluginResourceDTO extends PluginResource { + private String entry; +} diff --git a/backend/src/main/java/io/metersphere/listener/AppStartListener.java b/backend/src/main/java/io/metersphere/listener/AppStartListener.java index 173b5082d2..3ede6c7709 100644 --- a/backend/src/main/java/io/metersphere/listener/AppStartListener.java +++ b/backend/src/main/java/io/metersphere/listener/AppStartListener.java @@ -9,6 +9,7 @@ import io.metersphere.commons.utils.RunInterface; import io.metersphere.performance.service.PerformanceTestService; import io.metersphere.service.JarConfigService; import io.metersphere.service.ProjectService; +import io.metersphere.service.PluginService; import io.metersphere.service.ScheduleService; import io.metersphere.service.SystemParameterService; import io.metersphere.track.service.IssuesService; @@ -42,6 +43,9 @@ public class AppStartListener implements ApplicationListener resources = this.getMethod(path, file.getOriginalFilename()); + if (CollectionUtils.isNotEmpty(resources)) { + for (PluginResourceDTO resource : resources) { + PluginExample example = new PluginExample(); + example.createCriteria().andPluginIdEqualTo(resource.getPluginId()); + List plugins = pluginMapper.selectByExample(example); + if (CollectionUtils.isNotEmpty(plugins)) { + String delPath = plugins.get(0).getSourcePath(); + // this.closeJar(delPath); + FileUtils.deleteFile(delPath); + pluginMapper.deleteByExample(example); + } + this.create(resource, path, file.getOriginalFilename()); + } + } + } + return null; + } + + private void create(PluginResourceDTO resource, String path, String name) { + resource.getUiScripts().forEach(item -> { + PluginWithBLOBs plugin = new PluginWithBLOBs(); + plugin.setId(UUID.randomUUID().toString()); + plugin.setCreateTime(System.currentTimeMillis()); + plugin.setUpdateTime(System.currentTimeMillis()); + plugin.setName(item.getName()); + plugin.setPluginId(resource.getPluginId()); + plugin.setSourcePath(path); + plugin.setFormOption(item.getFormOption()); + plugin.setFormScript(item.getFormScript()); + plugin.setClazzName(item.getClazzName()); + plugin.setSourceName(name); + plugin.setExecEntry(resource.getEntry()); + plugin.setCreateUserId(SessionUtils.getUserId()); + pluginMapper.insert(plugin); + }); + } + + private List getMethod(String path, String fileName) { + List resources = new LinkedList<>(); + try { + this.loadJar(path); + List> classes = CommonUtil.getSubClass(fileName); + for (Class aClass : classes) { + Object instance = aClass.newInstance(); + Object pluginObj = aClass.getDeclaredMethod("init").invoke(instance); + if (pluginObj != null) { + PluginResourceDTO pluginResourceDTO = new PluginResourceDTO(); + BeanUtils.copyBean(pluginResourceDTO, (PluginResource) pluginObj); + pluginResourceDTO.setEntry(aClass.getName()); + resources.add(pluginResourceDTO); + } + } + } catch (Exception e) { + LogUtil.error("初始化脚本异常:" + e.getMessage()); + } + return resources; + } + + private void closeJar(String jarPath) { + File jarFile = new File(jarPath); + Method method = null; + try { + method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + } catch (NoSuchMethodException | SecurityException e1) { + e1.printStackTrace(); + } + // 获取方法的访问权限以便写回 + try { + method.setAccessible(true); + // 获取系统类加载器 + URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); + URL url = jarFile.toURI().toURL(); + method.invoke(classLoader, url); + classLoader.close(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + } + } + + private void loadJar(String jarPath) { + File jarFile = new File(jarPath); + // 从URLClassLoader类中获取类所在文件夹的方法,jar也可以认为是一个文件夹 + Method method = null; + try { + method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + } catch (NoSuchMethodException | SecurityException e1) { + e1.printStackTrace(); + } + // 获取方法的访问权限以便写回 + try { + method.setAccessible(true); + // 获取系统类加载器 + URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); + URL url = jarFile.toURI().toURL(); + method.invoke(classLoader, url); + } catch (Exception e) { + e.printStackTrace(); + } finally { + } + } + + public void loadPlugins() { + PluginExample example = new PluginExample(); + List plugins = pluginMapper.selectByExample(example); + if (CollectionUtils.isNotEmpty(plugins)) { + plugins.forEach(item -> { + this.loadJar(item.getSourcePath()); + }); + } + } + + public List list() { + PluginExample example = new PluginExample(); + List plugins = pluginMapper.selectByExample(example); + return plugins; + } + + public Plugin get(String pluginId) { + PluginExample example = new PluginExample(); + example.createCriteria().andPluginIdEqualTo(pluginId); + List plugins = pluginMapper.selectByExampleWithBLOBs(example); + if (CollectionUtils.isNotEmpty(plugins)) { + return plugins.get(0); + } + return null; + } + + public String delete(String id) { + Plugin plugin = pluginMapper.selectByPrimaryKey(id); + if (plugin != null) { + //通过pluginId判断是否还有其他脚本,无则清理加载的jar包 + PluginExample example = new PluginExample(); + example.createCriteria().andPluginIdEqualTo(plugin.getPluginId()); + List plugins = pluginMapper.selectByExample(example); + if (plugins.size() == 1) { + // this.closeJar(plugin.getSourcePath()); + FileUtils.deleteFile(plugin.getSourcePath()); + } + pluginMapper.deleteByPrimaryKey(id); + return "success"; + } + return "error"; + } + + public Object customMethod(PluginRequest request) { + try { + Class clazz = Class.forName(request.getEntry()); + Object instance = clazz.newInstance(); + Object pluginObj = clazz.getDeclaredMethod("customMethod", String.class).invoke(instance, request.getRequest()); + return pluginObj; + } catch (Exception ex) { + LogUtil.error("加载自定义方法失败:" + ex.getMessage()); + } + return null; + } +} diff --git a/backend/src/main/java/io/metersphere/service/utils/CommonUtil.java b/backend/src/main/java/io/metersphere/service/utils/CommonUtil.java new file mode 100644 index 0000000000..f7e77a928e --- /dev/null +++ b/backend/src/main/java/io/metersphere/service/utils/CommonUtil.java @@ -0,0 +1,93 @@ +package io.metersphere.service.utils; + +import com.github.pagehelper.util.StringUtil; +import io.metersphere.commons.utils.LogUtil; +import io.metersphere.plugin.core.api.UiScriptApi; +import org.reflections8.Reflections; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.PropertiesLoaderUtils; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.core.io.ClassPathResource; +import java.io.File; +import java.net.URL; +import java.util.*; + +public class CommonUtil { + //获取某个类的实现类 + public static List> getAllAssignedClass(Class cls) throws Exception { + List> classes = new ArrayList>(); + for (Class c : getClasses(cls)) { + if (cls.isAssignableFrom(c) && !cls.equals(c)) { + classes.add(c); + } + } + return classes; + } + + public static List> getClasses(Class cls) throws Exception { + String pk = cls.getPackage().getName(); + String path = pk.replace('.', '/'); + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + URL url = classloader.getResource(path); + return getClasses(new File(url.getFile()), pk); + } + + //根据路径获取 + public static List> getClasses(File dir, String pk) throws ClassNotFoundException { + List> classes = new ArrayList>(); + if (!dir.exists()) { + return classes; + } + for (File f : dir.listFiles()) { + if (f.isDirectory()) { + classes.addAll(getClasses(f, pk + "." + f.getName())); + } + String name = f.getName(); + if (name.endsWith(".class")) { + classes.add(Class.forName(pk + "." + name.substring(0, name.length() - 6))); + } + } + return classes; + } + + public static List> getSubClass(String fileName) throws Exception { + List> classes = new LinkedList<>(); + ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver(); + if (StringUtil.isNotEmpty(fileName) && fileName.endsWith(".jar")) { + fileName = fileName.substring(0, fileName.length() - 4); + } + LogUtil.info("获取到文件路径:" + fileName); + Resource resource = new ClassPathResource(fileName); + Properties inPro = PropertiesLoaderUtils.loadProperties(resource); + if (inPro != null) { + LogUtil.info("开始读取文件内容进行反射处理"); + Set entryObj = inPro.stringPropertyNames(); + if (entryObj != null) { + for (String entry : entryObj) { + try { + Class clazz = Class.forName(entry); + classes.add(clazz); + } catch (Exception e) { + LogUtil.error("反射类【" + entry + " 】失败:" + e.getMessage()); + e.printStackTrace(); + } + } + } + } + return classes; + } + + public static List> getSubClazz(String pac) { + List> classes = new LinkedList<>(); + try { + Reflections reflections = new Reflections(pac); + Set> subTypes = reflections.getSubTypesOf(UiScriptApi.class); + subTypes.forEach(x -> classes.add(x)); + } catch (Exception ex) { + LogUtil.error(ex.getMessage()); + ex.printStackTrace(); + } + return classes; + } +} diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java index c77c76bea0..e2678806c7 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java @@ -14,7 +14,7 @@ import io.metersphere.api.dto.definition.ApiTestCaseDTO; import io.metersphere.api.dto.definition.ApiTestCaseRequest; import io.metersphere.api.dto.definition.BatchRunDefinitionRequest; import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; -import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.MsThreadGroup; import io.metersphere.api.dto.definition.request.ParameterConfig; @@ -41,6 +41,7 @@ import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.*; import io.metersphere.dto.BaseSystemConfigDTO; import io.metersphere.log.vo.OperatingLogDetails; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.service.SystemParameterService; import io.metersphere.track.dto.PlanReportCaseDTO; import io.metersphere.track.dto.TestCaseReportStatusResultDTO; @@ -291,6 +292,8 @@ public class TestPlanApiCaseService { try { String api = caseWithBLOBs.getRequest(); JSONObject element = JSON.parseObject(api); + ElementUtil.dataFormatting(element); + LinkedList list = new LinkedList<>(); if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { LinkedList elements = mapper.readValue(element.getString("hashTree"), diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index 43f7e9a554..ed1bc41477 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -45,6 +45,7 @@ import io.metersphere.performance.request.RunTestPlanRequest; import io.metersphere.performance.service.MetricQueryService; import io.metersphere.performance.service.PerformanceReportService; import io.metersphere.performance.service.PerformanceTestService; +import io.metersphere.plugin.core.MsTestElement; import io.metersphere.service.IssueTemplateService; import io.metersphere.service.ScheduleService; import io.metersphere.service.SystemParameterService; @@ -970,6 +971,8 @@ public class TestPlanService { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); JSONObject element = JSON.parseObject(item.getScenarioDefinition()); + ElementUtil.dataFormatting(element); + MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class); group.setOnSampleError(scenario.getOnSampleError()); // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 diff --git a/backend/src/main/resources/db/migration/V95__v1.13_release.sql b/backend/src/main/resources/db/migration/V95__v1.13_release.sql new file mode 100644 index 0000000000..017c16e535 --- /dev/null +++ b/backend/src/main/resources/db/migration/V95__v1.13_release.sql @@ -0,0 +1,17 @@ +CREATE TABLE `plugin` ( + `id` varchar(50) NOT NULL COMMENT 'ID', + `name` varchar(300) DEFAULT NULL COMMENT 'plugin name', + `plugin_id` varchar(300) NOT NULL COMMENT 'Plugin id', + `clazz_name` varchar(500) NOT NULL COMMENT 'Plugin clazzName', + `source_path` varchar(300) NOT NULL COMMENT 'Plugin jar path', + `source_name` varchar(300) NOT NULL COMMENT 'Plugin jar name', + `form_option` longtext COMMENT 'plugin form option', + `form_script` longtext COMMENT 'plugin form script', + `exec_entry` varchar(300) DEFAULT NULL COMMENT 'plugin init entry class', + `create_time` bigint(13) DEFAULT NULL, + `update_time` bigint(13) DEFAULT NULL, + `create_user_id` varchar(64) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE utf8mb4_general_ci; \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 08b8939883..ea6d9431fc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,6 +11,7 @@ "dependencies": { "@ckeditor/ckeditor5-build-classic": "^18.0.0", "@ckeditor/ckeditor5-vue": "^1.0.1", + "@form-create/element-ui": "^2.5.8", "@fortawesome/fontawesome-svg-core": "^1.2.26", "@fortawesome/free-brands-svg-icons": "^5.13.0", "@fortawesome/free-regular-svg-icons": "^5.12.0", @@ -44,6 +45,7 @@ "md5": "^2.3.0", "mockjs": "^1.1.0", "nprogress": "^0.2.0", + "pdfjs-dist": "2.5.207", "sha.js": "^2.4.11", "vue": "2.6.14", "vue-calendar-heatmap": "^0.8.4", @@ -56,12 +58,11 @@ "vue-papa-parse": "^2.0.0", "vue-pdf": "^4.2.0", "vue-router": "^3.1.3", + "vue2-ace-editor": "0.0.15", "vuedraggable": "^2.24.3", "vuex": "^3.1.2", "xml-js": "^1.6.11", - "yan-progress": "^1.0.3", - "vue2-ace-editor": "0.0.15", - "pdfjs-dist": "2.5.207" + "yan-progress": "^1.0.3" }, "devDependencies": { "@vue/cli-plugin-babel": "^4.1.0", diff --git a/frontend/src/business/components/api/automation/api-automation.js b/frontend/src/business/components/api/automation/api-automation.js index 890745d200..ca1d603691 100644 --- a/frontend/src/business/components/api/automation/api-automation.js +++ b/frontend/src/business/components/api/automation/api-automation.js @@ -69,8 +69,16 @@ function getScenarioFiles(obj) { return scenarioFiles; } -export function saveScenario(url, scenario, scenarioDefinition, success) { +export function saveScenario(url, scenario, scenarioDefinition, _this,success) { let bodyFiles = getBodyUploadFiles(scenario, scenarioDefinition); + if (_this.$store.state.pluginFiles && _this.$store.state.pluginFiles.length > 0) { + _this.$store.state.pluginFiles.forEach(fileItem => { + if (fileItem.file) { + scenario.bodyFileRequestIds.push(fileItem.file.id); + bodyFiles.push(fileItem.file); + } + }); + } let scenarioFiles = getScenarioFiles(scenario); let formData = new FormData(); if (bodyFiles) { diff --git a/frontend/src/business/components/api/automation/scenario/DebugRun.vue b/frontend/src/business/components/api/automation/scenario/DebugRun.vue index e47d2a724d..f974534d6b 100644 --- a/frontend/src/business/components/api/automation/scenario/DebugRun.vue +++ b/frontend/src/business/components/api/automation/scenario/DebugRun.vue @@ -3,53 +3,59 @@ diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 11831074a4..cf2b5fded8 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -225,7 +225,7 @@ { @@ -471,12 +474,32 @@ export default { }, directives: {OutsideClick}, computed: { - buttons, projectId() { return getCurrentProjectID(); }, }, methods: { + initPlugins() { + let url = "/plugin/list"; + this.$get(url, response => { + let data = response.data; + if (data) { + data.forEach(item => { + let plugin = { + title: item.name, + show: this.showButton(item.name), + titleColor: "#555855", + titleBgColor: "#F4F4FF", + icon: "colorize", + click: () => { + this.addComponent(item.name, item) + } + } + this.buttonData.push(plugin); + }); + } + }); + }, stop() { let url = "/api/automation/stop/" + this.reportId; this.$get(url, response => { @@ -812,14 +835,16 @@ export default { outsideClick(e) { e.stopPropagation(); this.showAll(); + this.buttonData = buttons(this); + this.initPlugins(); }, fabClick() { - if (this.operatingElements.length < 1) { + if (this.operatingElements && this.operatingElements.length < 1) { this.$info("引用的场景或接口无法添加配置"); } }, - addComponent(type) { - setComponent(type, this); + addComponent(type, plugin) { + setComponent(type, this, plugin); }, nodeClick(data, node) { if (data.referenced != 'REF' && data.referenced != 'Deleted' && !data.disabled) { @@ -827,9 +852,13 @@ export default { } else { this.operatingElements = []; } + if (!this.operatingElements) { + this.operatingElements = ELEMENTS.get("ALL"); + } this.selectedTreeNode = data; this.selectedNode = node; this.$store.state.selectStep = data; + this.buttonData = buttons(this); }, suggestClick(node) { this.response = {}; @@ -864,6 +893,9 @@ export default { && stepArray[i].hashTree.length > 1) { stepArray[i].countController.proceed = true; } + if (!stepArray[i].clazzName) { + stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type); + } if (!stepArray[i].projectId) { // 如果自身没有ID并且场景有ID则赋值场景ID,否则赋值当前项目ID stepArray[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId; @@ -1115,7 +1147,7 @@ export default { if (dropType != "inner") { return true; } else if (dropType === "inner" && dropNode.data.referenced !== 'REF' && dropNode.data.referenced !== 'Deleted' - && ELEMENTS.get(dropNode.data.type).indexOf(draggingNode.data.type) != -1 && !draggingNode.data.disabled) { + && ELEMENTS.get(dropNode.data.type) && ELEMENTS.get(dropNode.data.type).indexOf(draggingNode.data.type) != -1 && !draggingNode.data.disabled) { return true; } return false; @@ -1145,9 +1177,10 @@ export default { this.$refs['currentScenario'].validate((valid) => { if (valid) { this.setParameter(); - saveScenario(this.path, this.currentScenario, this.scenarioDefinition, (response) => { + saveScenario(this.path, this.currentScenario, this.scenarioDefinition, this,(response) => { this.$success(this.$t('commons.save_success')); this.path = "/api/automation/update"; + this.$store.state.pluginFiles = []; if (response.data) { this.currentScenario.id = response.data.id; } @@ -1259,6 +1292,7 @@ export default { enableCookieShare: this.enableCookieShare, name: this.currentScenario.name, type: "scenario", + clazzName: TYPE_TO_C.get("scenario"), variables: this.currentScenario.variables, headers: this.currentScenario.headers, referenced: 'Created', diff --git a/frontend/src/business/components/api/automation/scenario/Setting.js b/frontend/src/business/components/api/automation/scenario/Setting.js index bdaa596207..a38c9ac46c 100644 --- a/frontend/src/business/components/api/automation/scenario/Setting.js +++ b/frontend/src/business/components/api/automation/scenario/Setting.js @@ -1,14 +1,14 @@ export const ELEMENTS = new Map([ - ['ALL', ["scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "IfController","TransactionController", "LoopController", "ConstantTimer", "JSR223Processor", "CustomizeReq"]], + ['ALL', ["Plugin","scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "IfController", "TransactionController", "LoopController", "ConstantTimer", "JSR223Processor", "CustomizeReq"]], ['scenario', ["HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "CASE", "OT_IMPORT", "IfController", "ConstantTimer", "JSR223Processor", "CustomizeReq"]], - ['HTTPSamplerProxy', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor',"Assertions", "Extract"]], - ['DubboSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor',"Assertions", "Extract"]], - ['JDBCSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor', "Assertions", "Extract"]], - ['TCPSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor', "Assertions", "Extract"]], - ['OT_IMPORT', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor', "Assertions", "Extract"]], - ['IfController', ["IfController","LoopController", "TransactionController","scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor',"Assertions", "Extract", "CustomizeReq"]], - ['TransactionController', ["TransactionController", "scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor', "Assertions", "Extract", "CustomizeReq"]], - ['LoopController', ["IfController", "TransactionController","scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor','JDBCPostProcessor', "Assertions", "Extract", "CustomizeReq"]], + ['HTTPSamplerProxy', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract"]], + ['DubboSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract"]], + ['JDBCSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract"]], + ['TCPSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract"]], + ['OT_IMPORT', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract"]], + ['IfController', ["IfController", "LoopController", "TransactionController", "scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract", "CustomizeReq"]], + ['TransactionController', ["TransactionController", "scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract", "CustomizeReq"]], + ['LoopController', ["IfController", "TransactionController", "scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", 'JDBCPreProcessor', 'JDBCPostProcessor', "Assertions", "Extract", "CustomizeReq"]], ['ConstantTimer', []], ['JSR223Processor', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract"]], ['JSR223PreProcessor', []], @@ -18,8 +18,8 @@ export const ELEMENTS = new Map([ ['Assertions', []], ['Extract', []], ['JmeterElement', []], - ['CustomizeReq', ["ConstantTimer", "JSR223PreProcessor","JSR223PostProcessor", "JDBCPostProcessor", "JDBCPreProcessor", "Assertions", "Extract"]], - ['MaxSamplerProxy', ["JSR223PreProcessor", "JSR223PostProcessor", "JDBCPreProcessor","JDBCPostProcessor","Assertions", "Extract"]], + ['CustomizeReq', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", "JDBCPostProcessor", "JDBCPreProcessor", "Assertions", "Extract"]], + ['MaxSamplerProxy', ["JSR223PreProcessor", "JSR223PostProcessor", "JDBCPreProcessor", "JDBCPostProcessor", "Assertions", "Extract"]], ['AllSamplerProxy', ["HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler"]], ['AllCanExecType', ["HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "JSR223Processor"]] ]) @@ -34,11 +34,36 @@ export const ELEMENT_TYPE = { JSR223Processor: "JSR223Processor", JSR223PreProcessor: "JSR223PreProcessor", JSR223PostProcessor: "JSR223PostProcessor", - JDBCPostProcessor : "JDBCPostProcessor", - JDBCPreProcessor : "JDBCPreProcessor", + JDBCPostProcessor: "JDBCPostProcessor", + JDBCPreProcessor: "JDBCPreProcessor", Assertions: "Assertions", Extract: "Extract", CustomizeReq: "CustomizeReq", - LoopController: "LoopController" + LoopController: "LoopController", + Plugin: "Plugin" } +export const TYPE_TO_C = new Map([ + ['scenario', "io.metersphere.api.dto.definition.request.MsScenario"], + ['HTTPSamplerProxy', "io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy"], + ['DubboSampler', "io.metersphere.api.dto.definition.request.sampler.MsDubboSampler"], + ['JDBCSampler', "io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler"], + ['TCPSampler', "io.metersphere.api.dto.definition.request.sampler.MsTCPSampler"], + ['IfController', "io.metersphere.api.dto.definition.request.controller.MsIfController"], + ['TransactionController', "io.metersphere.api.dto.definition.request.controller.MsTransactionController"], + ['LoopController', "io.metersphere.api.dto.definition.request.controller.MsLoopController"], + ['ConstantTimer', "io.metersphere.api.dto.definition.request.timer.MsConstantTimer"], + ['JSR223Processor', "io.metersphere.api.dto.definition.request.processors.MsJSR223Processor"], + ['JSR223PreProcessor', "io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor"], + ['JSR223PostProcessor', "io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor"], + ['JDBCPreProcessor', "io.metersphere.api.dto.definition.request.processors.pre.MsJDBCPreProcessor"], + ['JDBCPostProcessor', "io.metersphere.api.dto.definition.request.processors.post.MsJDBCPostProcessor"], + ['Assertions', "io.metersphere.api.dto.definition.request.assertions.MsAssertions"], + ['Extract', "io.metersphere.api.dto.definition.request.extract.MsExtract"], + ['JmeterElement', "io.metersphere.api.dto.definition.request.unknown.MsJmeterElement"], + ['TestPlan', "io.metersphere.api.dto.definition.request.MsTestPlan"], + ['ThreadGroup', "io.metersphere.api.dto.definition.request.MsThreadGroup"], + ['DNSCacheManager', "io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager"], + ['DebugSampler', "io.metersphere.api.dto.definition.request.sampler.MsDebugSampler"], + +]) diff --git a/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue b/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue index 58bcaa08fe..de57ec8209 100644 --- a/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue +++ b/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue @@ -6,7 +6,7 @@
{{ data.index }}
{{ title }} - {{ getMethod() }} + {{ getMethod() }} diff --git a/frontend/src/business/components/api/automation/scenario/common/MsPluginUpload.vue b/frontend/src/business/components/api/automation/scenario/common/MsPluginUpload.vue new file mode 100644 index 0000000000..4442524104 --- /dev/null +++ b/frontend/src/business/components/api/automation/scenario/common/MsPluginUpload.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/frontend/src/business/components/api/automation/scenario/component/ComponentConfig.vue b/frontend/src/business/components/api/automation/scenario/component/ComponentConfig.vue index b088bfe350..a8121fa117 100644 --- a/frontend/src/business/components/api/automation/scenario/component/ComponentConfig.vue +++ b/frontend/src/business/components/api/automation/scenario/component/ComponentConfig.vue @@ -10,170 +10,190 @@ diff --git a/frontend/src/business/components/api/automation/scenario/component/PluginComponent.vue b/frontend/src/business/components/api/automation/scenario/component/PluginComponent.vue new file mode 100644 index 0000000000..3f55a977ac --- /dev/null +++ b/frontend/src/business/components/api/automation/scenario/component/PluginComponent.vue @@ -0,0 +1,287 @@ + + + + + diff --git a/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue b/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue index 6ea491a20d..2657e0e73b 100644 --- a/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue @@ -682,7 +682,7 @@ export default { this.$refs['currentScenario'].validate((valid) => { if (valid) { this.setParameter(); - saveScenario(this.path, this.currentScenario, this.scenarioDefinition, (response) => { + saveScenario(this.path, this.currentScenario, this.scenarioDefinition, this,(response) => { this.$success(this.$t('commons.save_success')); this.path = "/api/automation/update"; if (response.data) { diff --git a/frontend/src/business/components/api/automation/scenario/menu/Menu.js b/frontend/src/business/components/api/automation/scenario/menu/Menu.js index d393a76f44..f34e762e55 100644 --- a/frontend/src/business/components/api/automation/scenario/menu/Menu.js +++ b/frontend/src/business/components/api/automation/scenario/menu/Menu.js @@ -1,151 +1,151 @@ import {ELEMENT_TYPE} from "@/business/components/api/automation/scenario/Setting"; -import {Assertions, ConstantTimer, Extract, IfController, JSR223Processor, JDBCProcessor,LoopController, TransactionController} from "@/business/components/api/definition/model/ApiTestModel"; +import {Assertions, ConstantTimer, Extract, IfController, JSR223Processor, JDBCProcessor, LoopController, TransactionController, PluginController} from "@/business/components/api/definition/model/ApiTestModel"; -export function buttons() { +export function buttons(this_) { let buttons = [ { - title: this.$t('api_test.definition.request.extract_param'), - show: this.showButton("Extract"), + title: this_.$t('api_test.definition.request.extract_param'), + show: this_.showButton("Extract"), titleColor: "#015478", titleBgColor: "#E6EEF2", icon: "colorize", click: () => { - this.addComponent('Extract') + this_.addComponent('Extract') } }, { - title: this.$t('api_test.definition.request.post_script'), - show: this.showButton("JSR223PostProcessor"), + title: this_.$t('api_test.definition.request.post_script'), + show: this_.showButton("JSR223PostProcessor"), titleColor: "#783887", titleBgColor: "#F2ECF3", icon: "skip_next", click: () => { - this.addComponent('JSR223PostProcessor') + this_.addComponent('JSR223PostProcessor') } }, { - title: this.$t('api_test.definition.request.pre_script'), - show: this.showButton("JSR223PreProcessor"), + title: this_.$t('api_test.definition.request.pre_script'), + show: this_.showButton("JSR223PreProcessor"), titleColor: "#B8741A", titleBgColor: "#F9F1EA", icon: "skip_previous", click: () => { - this.addComponent('JSR223PreProcessor') + this_.addComponent('JSR223PreProcessor') } }, { - title: this.$t('api_test.definition.request.post_sql'), - show: this.showButton("JDBCPostProcessor"), + title: this_.$t('api_test.definition.request.post_sql'), + show: this_.showButton("JDBCPostProcessor"), titleColor: "#1483F6", titleBgColor: "#F2ECF3", icon: "skip_next", click: () => { - this.addComponent('JDBCPostProcessor') + this_.addComponent('JDBCPostProcessor') } }, { - title: this.$t('api_test.definition.request.pre_sql'), - show: this.showButton("JDBCPreProcessor"), + title: this_.$t('api_test.definition.request.pre_sql'), + show: this_.showButton("JDBCPreProcessor"), titleColor: "#FE6F71", titleBgColor: "#F9F1EA", icon: "skip_previous", click: () => { - this.addComponent('JDBCPreProcessor') + this_.addComponent('JDBCPreProcessor') } }, { - title: this.$t('api_test.automation.customize_script'), - show: this.showButton("JSR223Processor"), + title: this_.$t('api_test.automation.customize_script'), + show: this_.showButton("JSR223Processor"), titleColor: "#7B4D12", titleBgColor: "#F1EEE9", icon: "code", click: () => { - this.addComponent('JSR223Processor') + this_.addComponent('JSR223Processor') } }, { - title: this.$t('api_test.automation.if_controller'), - show: this.showButton("IfController"), + title: this_.$t('api_test.automation.if_controller'), + show: this_.showButton("IfController"), titleColor: "#E6A23C", titleBgColor: "#FCF6EE", icon: "alt_route", click: () => { - this.addComponent('IfController') + this_.addComponent('IfController') } }, { - title: this.$t('api_test.automation.loop_controller'), - show: this.showButton("LoopController"), + title: this_.$t('api_test.automation.loop_controller'), + show: this_.showButton("LoopController"), titleColor: "#02A7F0", titleBgColor: "#F4F4F5", icon: "next_plan", click: () => { - this.addComponent('LoopController') + this_.addComponent('LoopController') } }, { - title: this.$t('api_test.automation.transcation_controller'), - show: this.showButton("TransactionController"), + title: this_.$t('api_test.automation.transcation_controller'), + show: this_.showButton("TransactionController"), titleColor: "#6D317C", titleBgColor: "#F4F4F5", icon: "alt_route", click: () => { - this.addComponent('TransactionController') + this_.addComponent('TransactionController') } }, { - title: this.$t('api_test.automation.wait_controller'), - show: this.showButton("ConstantTimer"), + title: this_.$t('api_test.automation.wait_controller'), + show: this_.showButton("ConstantTimer"), titleColor: "#67C23A", titleBgColor: "#F2F9EE", icon: "access_time", click: () => { - this.addComponent('ConstantTimer') + this_.addComponent('ConstantTimer') } }, { - title: this.$t('api_test.definition.request.assertions_rule'), - show: this.showButton("Assertions"), + title: this_.$t('api_test.definition.request.assertions_rule'), + show: this_.showButton("Assertions"), titleColor: "#A30014", titleBgColor: "#F7E6E9", icon: "next_plan", click: () => { - this.addComponent('Assertions') + this_.addComponent('Assertions') } }, { - title: this.$t('api_test.automation.customize_req'), - show: this.showButton("CustomizeReq"), + title: this_.$t('api_test.automation.customize_req'), + show: this_.showButton("CustomizeReq"), titleColor: "#008080", titleBgColor: "#EBF2F2", icon: "tune", click: () => { - this.addComponent('CustomizeReq') + this_.addComponent('CustomizeReq') } }, { - title: this.$t('api_test.automation.scenario_import'), - show: this.showButton("scenario"), + title: this_.$t('api_test.automation.scenario_import'), + show: this_.showButton("scenario"), titleColor: "#606266", titleBgColor: "#F4F4F5", icon: "movie", click: () => { - this.addComponent('scenario') + this_.addComponent('scenario') } }, { - title: this.$t('api_test.automation.api_list_import'), - show: this.showButton("HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler"), + title: this_.$t('api_test.automation.api_list_import'), + show: this_.showButton("HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler"), titleColor: "#F56C6C", titleBgColor: "#FCF1F1", icon: "api", - click: this.apiListImport + click: this_.apiListImport } ]; return buttons.filter(btn => btn.show); } -export function setComponent(type, _this) { +export function setComponent(type, _this, plugin) { switch (type) { case ELEMENT_TYPE.IfController: _this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new IfController()) : @@ -200,7 +200,7 @@ export function setComponent(type, _this) { _this.$refs.scenarioRelevance.open(); break; default: - _this.$refs.apiImport.open(); + _this.scenarioDefinition.push(new PluginController({type: plugin.name, pluginId: plugin.pluginId})); break; } if (_this.selectedNode) { diff --git a/frontend/src/business/components/api/definition/components/Run.vue b/frontend/src/business/components/api/definition/components/Run.vue index 9ace0847dc..f81fc2d609 100644 --- a/frontend/src/business/components/api/definition/components/Run.vue +++ b/frontend/src/business/components/api/definition/components/Run.vue @@ -5,6 +5,7 @@ import {getBodyUploadFiles, getCurrentProjectID, strMapToObj} from "@/common/js/utils"; import ThreadGroup from "./jmeter/components/thread-group"; import TestPlan from "./jmeter/components/test-plan"; +import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting"; export default { name: 'MsRun', @@ -70,14 +71,19 @@ export default { } let testPlan = new TestPlan(); + testPlan.clazzName = TYPE_TO_C.get(testPlan.type); let threadGroup = new ThreadGroup(); + threadGroup.clazzName = TYPE_TO_C.get(threadGroup.type); threadGroup.hashTree = []; testPlan.hashTree = [threadGroup]; this.runData.forEach(item => { item.projectId = projectId; + if (!item.clazzName) { + item.clazzName = TYPE_TO_C.get(item.type); + } threadGroup.hashTree.push(item); }) - let reqObj = {id: this.reportId, testElement: testPlan, type: this.type, projectId: projectId, environmentMap: strMapToObj(this.envMap)}; + let reqObj = {id: this.reportId, testElement: testPlan, type: this.type, clazzName: this.clazzName ? this.clazzName : TYPE_TO_C.get(this.type), projectId: projectId, environmentMap: strMapToObj(this.envMap)}; let bodyFiles = getBodyUploadFiles(reqObj, this.runData); if (this.runData[0].url) { reqObj.name = this.runData[0].url; diff --git a/frontend/src/business/components/api/definition/model/ApiTestModel.js b/frontend/src/business/components/api/definition/model/ApiTestModel.js index 3ffedfb2b0..524c714d76 100644 --- a/frontend/src/business/components/api/definition/model/ApiTestModel.js +++ b/frontend/src/business/components/api/definition/model/ApiTestModel.js @@ -1036,6 +1036,34 @@ export class IfController extends Controller { } } +export class PluginController extends BaseConfig { + constructor(options = {}) { + super("Plugin", options); + this.type = "Plugin"; + this.active = false; + this.enable = true; + this.hashTree = []; + this.set(options); + } + + isValid() { + if (!!this.operator && this.operator.indexOf("empty") > 0) { + return !!this.variable && !!this.operator; + } + return !!this.variable && !!this.operator && !!this.value; + } + + label() { + if (this.isValid()) { + let label = this.variable; + if (this.operator) label += " " + this.operator; + if (this.value) label += " " + this.value; + return label; + } + return ""; + } +} + export class LoopController extends Controller { constructor(options = {}) { super("LoopController", options); diff --git a/frontend/src/business/components/settings/plugin/JarConfig.vue b/frontend/src/business/components/settings/plugin/JarConfig.vue new file mode 100644 index 0000000000..9e4fa41400 --- /dev/null +++ b/frontend/src/business/components/settings/plugin/JarConfig.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/frontend/src/business/components/settings/plugin/PluginConfig.vue b/frontend/src/business/components/settings/plugin/PluginConfig.vue new file mode 100644 index 0000000000..427919870e --- /dev/null +++ b/frontend/src/business/components/settings/plugin/PluginConfig.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/frontend/src/business/components/settings/plugin/ScriptView.vue b/frontend/src/business/components/settings/plugin/ScriptView.vue new file mode 100644 index 0000000000..8843de22ef --- /dev/null +++ b/frontend/src/business/components/settings/plugin/ScriptView.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/frontend/src/business/components/settings/router.js b/frontend/src/business/components/settings/router.js index 0cace1c021..0d6a570ca9 100644 --- a/frontend/src/business/components/settings/router.js +++ b/frontend/src/business/components/settings/router.js @@ -132,26 +132,31 @@ export default { { path: 'operatingLog/system', component: () => import('@/business/components/settings/operatinglog/OperatingLog'), - name:'system', + name: 'system', meta: {system: true, title: 'operating_log.title', permissions: ['SYSTEM_OPERATING_LOG:READ']} }, { path: 'operatingLog/organization', component: () => import('@/business/components/settings/operatinglog/OperatingLog'), - name:'organization', + name: 'organization', meta: {organization: true, title: 'operating_log.title', permissions: ['ORGANIZATION_OPERATING_LOG:READ']} }, { path: 'operatingLog/workspace', component: () => import('@/business/components/settings/operatinglog/OperatingLog'), - name:'workspace', + name: 'workspace', meta: {workspace: true, title: 'operating_log.title', permissions: ['WORKSPACE_OPERATING_LOG:READ']} }, { path: 'operatingLog/project', - name:'project', + name: 'project', component: () => import('@/business/components/settings/operatinglog/OperatingLog'), meta: {project: true, title: 'operating_log.title', permissions: ['PROJECT_OPERATING_LOG:READ']} - } + }, + { + path: 'plugin', + component: () => import('@/business/components/settings/plugin/PluginConfig'), + meta: {system: true, title: 'plugin.title', permissions: ['SYSTEM_USER:READ']} + }, ] }; diff --git a/frontend/src/business/main.js b/frontend/src/business/main.js index 626d5eabf7..32c0d6bde4 100644 --- a/frontend/src/business/main.js +++ b/frontend/src/business/main.js @@ -23,6 +23,7 @@ import JsonSchemaEditor from './components/common/json-schema/schema/index'; import JSONPathPicker from 'vue-jsonpath-picker'; import VueClipboard from 'vue-clipboard2' import vueMinderEditor from 'vue-minder-editor-plus' +import formCreate from "@form-create/element-ui" import mavonEditor from 'mavon-editor' import 'mavon-editor/dist/css/index.css' @@ -33,6 +34,7 @@ Vue.use(vueMinderEditor) Vue.use(JsonSchemaEditor); import VuePapaParse from 'vue-papa-parse' Vue.use(VuePapaParse) +Vue.use(formCreate); Vue.config.productionTip = false; Vue.use(icon); diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 44efe8fbd3..251dfde712 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -1988,5 +1988,11 @@ export default { share: "Share", change_history: "Change history", change_content: "Change content" + }, + plugin: { + title: "Plug-in management", + script_entry: "Script execution entry", + plugin_id: "Plug-in id", + script_view: "View script", } }; diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index cf9c1dc0b1..8547d13b98 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -2000,5 +2000,11 @@ export default { share: "分享", change_history: "变更历史", change_content: "变更内容" + }, + plugin: { + title: "插件管理", + script_entry: "脚本执行入口", + plugin_id: "插件ID", + script_view: "查看脚本", } }; diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index e74faec050..27d7c01ff1 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -411,7 +411,7 @@ export default { jira_storytype: '需求類型', input_api_account: '請輸入賬號', input_api_password: '請輸入密碼', - input_api_pat:'請输入 Personal Access Token', + input_api_pat: '請输入 Personal Access Token', input_jira_url: '請輸入Jira地址,例:https://metersphere.atlassian.net/', input_jira_issuetype: '請輸入問題類型', input_jira_storytype: '請輸入需求類型', @@ -438,12 +438,12 @@ export default { azure_storytype: '需求類型', input_azure_issuetype: '請輸入問題類型', input_azure_storytype: '請輸入需求類型', - azure_pat:'PersonalAccessTokens', - azure_devops_url:'Azure Devops 地址', - azure_organization_id:'Azure 組織ID', - input_azure_pat:'請輸入 Personal Access Token', - input_azure_url:'請輸入 Azure Devops 地址', - input_azure_id:'請輸入 Azure 組織ID', + azure_pat: 'PersonalAccessTokens', + azure_devops_url: 'Azure Devops 地址', + azure_organization_id: 'Azure 組織ID', + input_azure_pat: '請輸入 Personal Access Token', + input_azure_url: '請輸入 Azure Devops 地址', + input_azure_id: '請輸入 Azure 組織ID', use_tip_azure: 'Azure Devops 地址+令牌(賬戶設置-個人訪問令牌-創建令牌)', } }, @@ -518,7 +518,7 @@ export default { select_project: '請選擇項目', select_group: '請選擇用戶組', add_user_group_batch: '批量添加用戶組', - add_project_batch : '批量添加到項目', + add_project_batch: '批量添加到項目', add_project_batch_tip: '默認為成員添加只讀用戶組(系統)', }, group: { @@ -2000,5 +2000,11 @@ export default { share: "分享", change_history: "變更歷史", change_content: "變更内容" + }, + plugin: { + title: "插件管理", + script_entry: "脚本执行入口", + plugin_id: "插件ID", + script_view: "查看腳本", } }; diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index a4e0c85e3a..70e22bc8b8 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -25,6 +25,7 @@ const state = { testPlanViewSelectNode: {}, selectStep: {}, currentApiCase: {}, + pluginFiles: [], } const store = new Vuex.Store({