From 37893657463dc125e3937d0c60f4dc0f1bc47993 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 6 Jan 2021 14:49:33 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=BE=AA=E7=8E=AF=E6=8E=A7=E5=88=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/service/HistoricalDataUpgradeService.java | 12 +++++++----- .../api/automation/scenario/EditApiScenario.vue | 10 ++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) 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 4e9358e6c2..c21cecceaf 100644 --- a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java +++ b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java @@ -250,11 +250,13 @@ public class HistoricalDataUpgradeService { if (!end.exists()) { end.mkdir(); } - for (String temp : filePath) { - //添加满足情况的条件 - if (new File(sourcePathDir + File.separator + temp).isFile()) { - //为文件则进行拷贝 - copyFile(sourcePathDir + File.separator + temp, newPathDir + File.separator + temp); + if (filePath != null) { + for (String temp : filePath) { + //添加满足情况的条件 + if (new File(sourcePathDir + File.separator + temp).isFile()) { + //为文件则进行拷贝 + copyFile(sourcePathDir + File.separator + temp, newPathDir + File.separator + temp); + } } } } diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 0fcd3a79ab..a68e317c9a 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -387,6 +387,16 @@ this.addComponent('IfController') } }, + { + title: this.$t('api_test.automation.if_controller'), + show: this.showButton("LoopController"), + titleColor: "#02A7F0", + titleBgColor: "#F4F4F5", + icon: "alt_route", + click: () => { + this.addComponent('IfController') + } + }, { title: this.$t('api_test.automation.wait_controller'), show: this.showButton("ConstantTimer"), From 625085c0a66033891f9f04bf5ff04e0b63851af5 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 6 Jan 2021 17:10:42 +0800 Subject: [PATCH 2/7] =?UTF-8?q?fix:=20swagger3=20=E7=A9=BA=E6=8C=87?= =?UTF-8?q?=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/io/metersphere/api/parse/Swagger3Parser.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/main/java/io/metersphere/api/parse/Swagger3Parser.java b/backend/src/main/java/io/metersphere/api/parse/Swagger3Parser.java index ac6ae883fa..0498ec4ec2 100644 --- a/backend/src/main/java/io/metersphere/api/parse/Swagger3Parser.java +++ b/backend/src/main/java/io/metersphere/api/parse/Swagger3Parser.java @@ -333,6 +333,9 @@ public class Swagger3Parser extends SwaggerAbstractParser { } private Object parseSchemaProperties(Schema schema, Set refSet, Map infoMap) { + if (schema == null) { + return null; + } Map properties = schema.getProperties(); if (MapUtils.isEmpty(properties)) { return null; From 32b8f17ba09aae5635878c661a3cd6d26e581482 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 6 Jan 2021 18:10:48 +0800 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20=E6=96=AD=E8=A8=80=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E6=97=B6=E8=8E=B7=E5=8F=96=E4=B8=8D=E5=88=B0=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/api/jmeter/APIBackendListenerClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index 79bb79e42d..1ae3f91e26 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -325,7 +325,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl requestResult.addPassAssertions(); } //xpath 提取错误会添加断言错误 - if (!responseAssertionResult.getMessage().contains("The required item type of the first operand of")) { + if (StringUtils.isNotBlank(responseAssertionResult.getMessage()) && !responseAssertionResult.getMessage().contains("The required item type of the first operand of")) { responseResult.getAssertions().add(responseAssertionResult); } } From e012d438896af3e0623e079076dfbddde1d9f298 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 6 Jan 2021 18:21:25 +0800 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20=E6=96=AD=E8=A8=80=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E7=A9=BA=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/api/jmeter/APIBackendListenerClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index 1ae3f91e26..feb3e61052 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -325,7 +325,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl requestResult.addPassAssertions(); } //xpath 提取错误会添加断言错误 - if (StringUtils.isNotBlank(responseAssertionResult.getMessage()) && !responseAssertionResult.getMessage().contains("The required item type of the first operand of")) { + if (StringUtils.isBlank(responseAssertionResult.getMessage()) || !responseAssertionResult.getMessage().contains("The required item type of the first operand of")) { responseResult.getAssertions().add(responseAssertionResult); } } From f096e1e52b2ec47434b8e97f6fb2610742be135b Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 6 Jan 2021 18:26:52 +0800 Subject: [PATCH 5/7] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=BE=AA=E7=8E=AF=E6=8E=A7=E5=88=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/definition/request/MsTestElement.java | 4 +- .../request/controller/MsLoopController.java | 126 ++++++++++++ .../controller/loop/CountController.java | 10 + .../controller/loop/MsForEachController.java | 10 + .../controller/loop/MsWhileController.java | 11 + .../service/HistoricalDataUpgradeService.java | 4 + .../automation/scenario/EditApiScenario.vue | 66 +++--- .../automation/scenario/LoopController.vue | 189 ++++++++++++++++++ .../api/automation/scenario/Setting.js | 6 +- .../api/definition/model/ApiTestModel.js | 32 +++ frontend/src/i18n/en-US.js | 16 +- frontend/src/i18n/zh-CN.js | 15 +- frontend/src/i18n/zh-TW.js | 16 +- 13 files changed, 460 insertions(+), 45 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/CountController.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsForEachController.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsWhileController.java create mode 100644 frontend/src/business/components/api/automation/scenario/LoopController.vue 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/MsTestElement.java index 54f8dc608e..d5e6ee61b7 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/MsTestElement.java @@ -11,6 +11,7 @@ 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.extract.MsExtract; import io.metersphere.api.dto.definition.request.processors.MsJSR223Processor; import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor; @@ -56,11 +57,12 @@ import java.util.List; @JsonSubTypes.Type(value = MsConstantTimer.class, name = "ConstantTimer"), @JsonSubTypes.Type(value = MsIfController.class, name = "IfController"), @JsonSubTypes.Type(value = MsScenario.class, name = "scenario"), + @JsonSubTypes.Type(value = MsLoopController.class, name = "LoopController"), }) @JSONType(seeAlso = {MsHTTPSamplerProxy.class, MsHeaderManager.class, MsJSR223Processor.class, MsJSR223PostProcessor.class, MsJSR223PreProcessor.class, MsTestPlan.class, MsThreadGroup.class, AuthManager.class, MsAssertions.class, - MsExtract.class, MsTCPSampler.class, MsDubboSampler.class, MsJDBCSampler.class, MsConstantTimer.class, MsIfController.class, MsScenario.class}, typeKey = "type") + MsExtract.class, MsTCPSampler.class, MsDubboSampler.class, MsJDBCSampler.class, MsConstantTimer.class, MsIfController.class, MsScenario.class, MsLoopController.class}, typeKey = "type") @Data public abstract class MsTestElement { private String type; 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 new file mode 100644 index 0000000000..7f5390287a --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java @@ -0,0 +1,126 @@ +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.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 lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.control.ForeachController; +import org.apache.jmeter.control.GenericController; +import org.apache.jmeter.control.LoopController; +import org.apache.jmeter.control.WhileController; +import org.apache.jmeter.save.SaveService; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jorphan.collections.HashTree; + +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = true) +@JSONType(typeName = "LoopController") +public class MsLoopController extends MsTestElement { + private String type = "LoopController"; + @JSONField(ordinal = 20) + private String loopType; + + @JSONField(ordinal = 21) + private CountController countController; + + @JSONField(ordinal = 22) + private MsForEachController forEachController; + + @JSONField(ordinal = 23) + private MsWhileController whileController; + + public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { + if (!this.isEnable()) { + return; + } + GenericController controller = controller(); + if (controller == null) + return; + + final HashTree groupTree = tree.add(controller); + if (CollectionUtils.isNotEmpty(hashTree)) { + hashTree.forEach(el -> { + el.toHashTree(groupTree, el.getHashTree(), config); + }); + } + } + + private LoopController loopController() { + LoopController loopController = new LoopController(); + loopController.setEnabled(true); + loopController.setName(this.getLabel()); + loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName()); + loopController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("LoopControlPanel")); + loopController.setContinueForever(countController.isProceed()); + loopController.setLoops(countController.getLoops()); + return loopController; + } + + public String getCondition() { + String variable = "\"" + this.whileController.getVariable() + "\""; + String operator = this.whileController.getOperator(); + String value = "\"" + this.whileController.getValue() + "\""; + + if (StringUtils.contains(operator, "~")) { + value = "\".*" + this.whileController.getValue() + ".*\""; + } + + if (StringUtils.equals(operator, "is empty")) { + variable = "empty(" + variable + ")"; + operator = ""; + value = ""; + } + + if (StringUtils.equals(operator, "is not empty")) { + variable = "!empty(" + variable + ")"; + operator = ""; + value = ""; + } + return "${__jexl3(" + variable + operator + value + ")}"; + } + + private WhileController whileController() { + WhileController controller = new WhileController(); + controller.setEnabled(true); + controller.setName(this.getLabel()); + controller.setProperty(TestElement.TEST_CLASS, WhileController.class.getName()); + controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("WhileControllerGui")); + controller.setCondition(getCondition()); + return controller; + } + + private ForeachController foreachController() { + ForeachController controller = new ForeachController(); + controller.setEnabled(true); + controller.setName(this.getLabel()); + controller.setProperty(TestElement.TEST_CLASS, ForeachController.class.getName()); + controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ForeachControlPanel")); + controller.setInputVal(this.forEachController.getInputVal()); + controller.setReturnVal(this.forEachController.getReturnVal()); + controller.setUseSeparator(true); + return controller; + } + + private GenericController controller() { + if (StringUtils.equals(this.loopType, "WHILE") && this.whileController != null) { + return whileController(); + } + if (StringUtils.equals(this.loopType, "FOREACH") && this.forEachController != null) { + return foreachController(); + } + if (StringUtils.equals(this.loopType, "LOOP_COUNT") && this.countController != null) { + return loopController(); + } + return null; + } + +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/CountController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/CountController.java new file mode 100644 index 0000000000..808b67cc9e --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/CountController.java @@ -0,0 +1,10 @@ +package io.metersphere.api.dto.definition.request.controller.loop; + +import lombok.Data; + +@Data +public class CountController { + private int loops; + private int interval; + private boolean proceed; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsForEachController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsForEachController.java new file mode 100644 index 0000000000..30a4a59e7f --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsForEachController.java @@ -0,0 +1,10 @@ +package io.metersphere.api.dto.definition.request.controller.loop; + +import lombok.Data; + +@Data +public class MsForEachController { + private String inputVal; + private String returnVal; + private String interval; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsWhileController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsWhileController.java new file mode 100644 index 0000000000..7781abbb0b --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/loop/MsWhileController.java @@ -0,0 +1,11 @@ +package io.metersphere.api.dto.definition.request.controller.loop; + +import lombok.Data; + +@Data +public class MsWhileController { + private String variable; + private String operator; + private String value; + private int timeout; +} 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 c21cecceaf..8220ca72e5 100644 --- a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java +++ b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java @@ -110,6 +110,10 @@ public class HistoricalDataUpgradeService { BeanUtils.copyBean(element, request1); ((MsHTTPSamplerProxy) element).setProtocol(RequestType.HTTP); ((MsHTTPSamplerProxy) element).setArguments(request1.getParameters()); + if (StringUtils.isEmpty(element.getName())) { + element.setName(request1.getPath()); + } + element.setType("HTTPSamplerProxy"); } if (request instanceof DubboRequest) { diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index a68e317c9a..ebe3dc5fb4 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -152,6 +152,8 @@ + + @@ -168,7 +170,8 @@ - + @@ -227,7 +230,7 @@ + + diff --git a/frontend/src/business/components/api/automation/scenario/Setting.js b/frontend/src/business/components/api/automation/scenario/Setting.js index 46fbef2fb8..a25c6d9f72 100644 --- a/frontend/src/business/components/api/automation/scenario/Setting.js +++ b/frontend/src/business/components/api/automation/scenario/Setting.js @@ -1,5 +1,5 @@ export const ELEMENTS = new Map([ - ['ALL', ["scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "IfController", "ConstantTimer", "JSR223Processor", "CustomizeReq"]], + ['ALL', ["scenario", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "IfController", "LoopController", "ConstantTimer", "JSR223Processor", "CustomizeReq"]], ['scenario', ["HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "CASE", "OT_IMPORT", "IfController", "ConstantTimer", "JSR223Processor", "CustomizeReq"]], ['HTTPSamplerProxy', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract"]], ['DubboSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract"]], @@ -7,6 +7,7 @@ export const ELEMENTS = new Map([ ['TCPSampler', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract"]], ['OT_IMPORT', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract"]], ['IfController', ["IfController", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract", "CustomizeReq"]], + ['LoopController', ["IfController", "HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "OT_IMPORT", "ConstantTimer", "JSR223Processor", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract", "CustomizeReq"]], ['ConstantTimer', []], ['JSR223Processor', ["ConstantTimer", "JSR223PreProcessor", "JSR223PostProcessor", "Assertions", "Extract"]], ['JSR223PreProcessor', []], @@ -27,6 +28,7 @@ export const ELEMENT_TYPE = { JSR223PostProcessor: "JSR223PostProcessor", Assertions: "Assertions", Extract: "Extract", - CustomizeReq: "CustomizeReq" + CustomizeReq: "CustomizeReq", + LoopController: "LoopController" } diff --git a/frontend/src/business/components/api/definition/model/ApiTestModel.js b/frontend/src/business/components/api/definition/model/ApiTestModel.js index 1be3b0c169..f6ef40f9f2 100644 --- a/frontend/src/business/components/api/definition/model/ApiTestModel.js +++ b/frontend/src/business/components/api/definition/model/ApiTestModel.js @@ -1016,6 +1016,38 @@ export class IfController extends Controller { } } +export class LoopController extends Controller { + constructor(options = {}) { + super("LoopController", options); + this.type = "LoopController"; + this.active = false; + this.loopType = "LOOP_COUNT"; + this.countController = {loops: 0, interval: 0, proceed: false}; + this.forEachController = {inputVal: "", returnVal: "", interval: 0}; + this.whileController = {variable: "", operator: "", value: "", timeout: 0}; + 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 Timer extends BaseConfig { static TYPES = { CONSTANT_TIMER: "Constant Timer", diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 61611f4450..d53f7e78ab 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -540,6 +540,7 @@ export default { res_param: "Response content", batch_delete: "Batch deletion", delete_confirm: "Confirm deletion", + delete_confirm_step: "Confirm deletion step", assertions_rule: "Assertion rule", response_header: "Response header", response_body: "Response body", @@ -570,6 +571,7 @@ export default { external_import: "External import", wait_controller: "Wait controller", if_controller: "If controller", + loop_controller: "Loop Controller", scenario_import: "Scenario import", customize_script: "Customize script", customize_req: "Customize req", @@ -1255,8 +1257,8 @@ export default { host: 'Host number cannot be empty', port: 'Port cannot be empty', account: 'Account cannot be empty', - test_recipients:'Test recipients', - tip:'Tip: use as test mail recipient only', + test_recipients: 'Test recipients', + tip: 'Tip: use as test mail recipient only', }, i18n: { @@ -1410,5 +1412,15 @@ export default { nothing: "Nothing", preview: "Preview", add_custom: "Add Custom Prop" + }, + loop: { + loops_title: "loops", + foreach: "ForEach", + while: "While", + loops: "loops", + interval: "interval", + proceed: "proceed", + timeout: "timeout", } + }; diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 4e935f35b5..3ae529230a 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -539,6 +539,7 @@ export default { res_param: "响应内容", batch_delete: "批量删除", delete_confirm: "确认删除接口", + delete_confirm_step: "确认删除步骤", assertions_rule: "断言规则", response_header: "响应头", response_body: "响应体", @@ -569,6 +570,7 @@ export default { external_import: "外部导入", wait_controller: "等待控制器", if_controller: "条件控制器", + loop_controller: "循环控制器", scenario_import: "场景导入", customize_script: "自定义脚本", customize_req: "自定义请求", @@ -1256,8 +1258,8 @@ export default { host: '主机号不能为空', port: '端口号不能为空', account: '账户不能为空', - test_recipients:'测试收件人', - tip:'提示:仅用来作为测试邮件收件人', + test_recipients: '测试收件人', + tip: '提示:仅用来作为测试邮件收件人', }, i18n: { home: '首页', @@ -1410,5 +1412,14 @@ export default { nothing: "无", preview: "预览", add_custom: "添加自定义属性" + }, + loop: { + loops_title: "次数循环", + foreach: "ForEach 循环", + while: "While 循环", + loops: "循环次数", + interval: "循环间隔", + proceed: "成功后继续循环", + timeout: "循环超时时间", } }; diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 11fddfe1e5..6e5e37511b 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -539,6 +539,7 @@ export default { res_param: "響應内容", batch_delete: "批量删除", delete_confirm: "確認刪除接口", + delete_confirm_step: "確認刪除步骤", assertions_rule: "斷言規則", response_header: "響應頭", response_body: "響應體", @@ -569,6 +570,7 @@ export default { external_import: "外部導入", wait_controller: "等待控制器", if_controller: "條件控制器", + loop_controller: "循环控制器", scenario_import: "場景導入", customize_script: "自定義脚本", customize_req: "自定義請求", @@ -1255,8 +1257,8 @@ export default { host: '主機號不能為空', port: '端口號不能為空', account: '賬戶不能為空', - test_recipients:'測試收件人', - tip:'提示:僅用來作為測試郵件收件人', + test_recipients: '測試收件人', + tip: '提示:僅用來作為測試郵件收件人', }, i18n: { home: '首頁', @@ -1409,5 +1411,15 @@ export default { nothing: "无", preview: "预览", add_custom: "添加自定义属性" + }, + loop: { + loops_title: "次數循環", + foreach: "ForEach 循環", + while: "While 循環", + loops: "循環次数", + interval: "循環間隔", + proceed: "成功後繼續循環", + timeout: "循環超時時間", } + }; From 4dfaa1c463ef49c39ea6ca3aa08c206624ba8e02 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 6 Jan 2021 18:34:17 +0800 Subject: [PATCH 6/7] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=EF=BC=8Csql=E7=B1=BB=E5=9E=8B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=BA=90=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/service/HistoricalDataUpgradeService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 8220ca72e5..afd82bd0bb 100644 --- a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java +++ b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java @@ -122,9 +122,8 @@ public class HistoricalDataUpgradeService { element.setType("DubboSampler"); } if (request instanceof SqlRequest) { - element = new MsJDBCSampler(); - SqlRequest request1 = (SqlRequest) request; - BeanUtils.copyBean(element, request1); + String requestJson = JSON.toJSONString(request); + element = JSON.parseObject(requestJson, MsJDBCSampler.class); element.setType("JDBCSampler"); } if (request instanceof TCPRequest) { From 540aba788cc8b670ec952744a8030fcb63a4beda Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 6 Jan 2021 18:55:25 +0800 Subject: [PATCH 7/7] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E7=BC=BA=E9=99=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metersphere/api/dto/EnvironmentDTO.java | 10 +++++ .../service/HistoricalDataUpgradeService.java | 38 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/dto/EnvironmentDTO.java diff --git a/backend/src/main/java/io/metersphere/api/dto/EnvironmentDTO.java b/backend/src/main/java/io/metersphere/api/dto/EnvironmentDTO.java new file mode 100644 index 0000000000..8bff389e5d --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/EnvironmentDTO.java @@ -0,0 +1,10 @@ +package io.metersphere.api.dto; + +import io.metersphere.api.dto.scenario.DatabaseConfig; +import lombok.Data; + +@Data +public class EnvironmentDTO { + private String environmentId; + private DatabaseConfig databaseConfig; +} 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 afd82bd0bb..cb8aeb52fa 100644 --- a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java +++ b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java @@ -1,6 +1,8 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.metersphere.api.dto.EnvironmentDTO; import io.metersphere.api.dto.SaveHistoricalDataUpgrade; import io.metersphere.api.dto.automation.ScenarioStatus; import io.metersphere.api.dto.definition.request.MsScenario; @@ -17,6 +19,7 @@ import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; import io.metersphere.api.dto.definition.request.timer.MsConstantTimer; import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.Scenario; +import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.dto.scenario.request.*; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.ApiScenarioMapper; @@ -48,6 +51,9 @@ public class HistoricalDataUpgradeService { private ExtApiScenarioMapper extApiScenarioMapper; @Resource SqlSessionFactory sqlSessionFactory; + @Resource + ApiTestEnvironmentService apiTestEnvironmentService; + private Map environmentDTOMap; private int getNextNum(String projectId) { ApiScenario apiScenario = extApiScenarioMapper.getNextNum(projectId); @@ -122,8 +128,14 @@ public class HistoricalDataUpgradeService { element.setType("DubboSampler"); } if (request instanceof SqlRequest) { - String requestJson = JSON.toJSONString(request); - element = JSON.parseObject(requestJson, MsJDBCSampler.class); + element = new MsJDBCSampler(); + SqlRequest request1 = (SqlRequest) request; + BeanUtils.copyBean(element, request1); + EnvironmentDTO dto = environmentDTOMap.get(request1.getDataSource()); + if (dto != null) { + ((MsJDBCSampler) element).setEnvironmentId(dto.getEnvironmentId()); + ((MsJDBCSampler) element).setDataSource(dto.getDatabaseConfig()); + } element.setType("JDBCSampler"); } if (request instanceof TCPRequest) { @@ -315,6 +327,9 @@ public class HistoricalDataUpgradeService { } public String upgrade(SaveHistoricalDataUpgrade saveHistoricalDataUpgrade) { + // 初始化环境,获取数据源 + getDataSource(saveHistoricalDataUpgrade.getProjectId()); + ApiTestExample example = new ApiTestExample(); example.createCriteria().andIdIn(saveHistoricalDataUpgrade.getTestIds()); List blobs = apiTestMapper.selectByExampleWithBLOBs(example); @@ -337,4 +352,23 @@ public class HistoricalDataUpgradeService { sqlSession.flushStatements(); return null; } + + private void getDataSource(String projectId) { + List environments = apiTestEnvironmentService.list(projectId); + environmentDTOMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(environments)) { + environments.forEach(environment -> { + EnvironmentConfig envConfig = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class); + if (CollectionUtils.isNotEmpty(envConfig.getDatabaseConfigs())) { + envConfig.getDatabaseConfigs().forEach(item -> { + EnvironmentDTO dto = new EnvironmentDTO(); + dto.setDatabaseConfig(item); + dto.setEnvironmentId(environment.getId()); + environmentDTOMap.put(item.getId(), dto); + }); + } + }); + } + } + }