From 08b973c03e3b41c5609b6c64d9128427a85c27db Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 14 Oct 2020 10:55:52 +0800 Subject: [PATCH 01/12] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20POST=20=E6=94=AF=E6=8C=81=20multipart/form-data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/dto/scenario/request/HttpRequest.java | 2 + .../controller/TestController.java | 9 ++++ backend/src/main/java/io/metersphere/xpack | 2 +- .../components/request/ApiHttpRequestForm.vue | 48 +++++++++++-------- .../business/components/api/test/model/JMX.js | 1 + .../api/test/model/ScenarioModel.js | 3 +- frontend/src/business/components/xpack | 2 +- frontend/src/i18n/en-US.js | 1 + frontend/src/i18n/zh-CN.js | 1 + frontend/src/i18n/zh-TW.js | 1 + 10 files changed, 46 insertions(+), 24 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/dto/scenario/request/HttpRequest.java b/backend/src/main/java/io/metersphere/api/dto/scenario/request/HttpRequest.java index f43fcc41c7..74b497d07c 100644 --- a/backend/src/main/java/io/metersphere/api/dto/scenario/request/HttpRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/scenario/request/HttpRequest.java @@ -35,4 +35,6 @@ public class HttpRequest extends Request { private Long responseTimeout; @JSONField(ordinal = 16) private Boolean followRedirects; + @JSONField(ordinal = 17) + private Boolean doMultipartPost; } diff --git a/backend/src/main/java/io/metersphere/controller/TestController.java b/backend/src/main/java/io/metersphere/controller/TestController.java index c3b7c033af..9783d98572 100644 --- a/backend/src/main/java/io/metersphere/controller/TestController.java +++ b/backend/src/main/java/io/metersphere/controller/TestController.java @@ -25,6 +25,15 @@ public class TestController { return jsonObject; } + @PostMapping(value = "/multipart", consumes = {"multipart/form-data"}) + public Object testMultipart(@RequestPart(value = "id") String id, @RequestPart(value = "user") User user, @RequestParam(value = "name") String name) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("id", id); + jsonObject.put("user", user.getName()); + jsonObject.put("name", name); + return jsonObject; + } + @GetMapping(value = "/{str}") public Object getString(@PathVariable String str) throws InterruptedException { if (StringUtils.equals("error", str)) { diff --git a/backend/src/main/java/io/metersphere/xpack b/backend/src/main/java/io/metersphere/xpack index ee74568be0..cf6b065263 160000 --- a/backend/src/main/java/io/metersphere/xpack +++ b/backend/src/main/java/io/metersphere/xpack @@ -1 +1 @@ -Subproject commit ee74568be0beba46da19616f5832e83f9164c688 +Subproject commit cf6b06526324326a563d933e07118fac014a63b4 diff --git a/frontend/src/business/components/api/test/components/request/ApiHttpRequestForm.vue b/frontend/src/business/components/api/test/components/request/ApiHttpRequestForm.vue index 4999ba3842..3e0e43b21a 100644 --- a/frontend/src/business/components/api/test/components/request/ApiHttpRequestForm.vue +++ b/frontend/src/business/components/api/test/components/request/ApiHttpRequestForm.vue @@ -39,6 +39,7 @@ :active-text="$t('api_test.request.refer_to_environment')" @change="useEnvironmentChange"> {{$t('api_test.request.follow_redirects')}} + {{$t('api_test.request.do_multipart_post')}} diff --git a/frontend/src/business/components/api/test/model/JMX.js b/frontend/src/business/components/api/test/model/JMX.js index 0d02ecff8c..6c57e47486 100644 --- a/frontend/src/business/components/api/test/model/JMX.js +++ b/frontend/src/business/components/api/test/model/JMX.js @@ -337,6 +337,7 @@ export class HTTPSamplerProxy extends DefaultTestElement { } this.boolProp("HTTPSampler.use_keepalive", options.keepalive, true); + this.boolProp("HTTPSampler.DO_MULTIPART_POST", options.doMultipartPost, false); } } diff --git a/frontend/src/business/components/api/test/model/ScenarioModel.js b/frontend/src/business/components/api/test/model/ScenarioModel.js index e1c8d79763..a10d6e3c56 100644 --- a/frontend/src/business/components/api/test/model/ScenarioModel.js +++ b/frontend/src/business/components/api/test/model/ScenarioModel.js @@ -346,6 +346,7 @@ export class HttpRequest extends Request { this.environment = options.environment; this.useEnvironment = options.useEnvironment; this.debugReport = undefined; + this.doMultipartPost = options.doMultipartPost; this.connectTimeout = options.connectTimeout || 60 * 1000; this.responseTimeout = options.responseTimeout; this.followRedirects = options.followRedirects === undefined ? true : options.followRedirects; @@ -987,7 +988,7 @@ class JMXHttpRequest { this.connectTimeout = request.connectTimeout; this.responseTimeout = request.responseTimeout; this.followRedirects = request.followRedirects; - + this.doMultipartPost = request.doMultipartPost; } } diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index cc38137a69..06d935cd1d 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit cc38137a69a0f20fadece9c0f9f50a9468c4ace9 +Subproject commit 06d935cd1d22ab36f09763745c2aff8ad3fb08c1 diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 9986e5cf4a..0fa27d7b0d 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -504,6 +504,7 @@ export default { connect_timeout: "Connect Timeout", response_timeout: "Response Timeout", follow_redirects: "Follow Redirects", + do_multipart_post: "Use multipart/form-data for POST", body_upload_limit_size: "The file size does not exceed 500 MB", condition: "condition", condition_variable: "Variable, e.g: ${var}", diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 3ca1f88a10..6ca3aa5277 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -505,6 +505,7 @@ export default { connect_timeout: "连接超时", response_timeout: "响应超时", follow_redirects: "跟随重定向", + do_multipart_post: "对 POST 使用 multipart/form-data", body_upload_limit_size: "上传文件大小不能超过 500 MB!", condition: "条件", condition_variable: "变量,例如: ${var}", diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index f2ca497ec1..0619038219 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -505,6 +505,7 @@ export default { connect_timeout: "連接超時", response_timeout: "響應超時", follow_redirects: "跟隨重定向", + do_multipart_post: "對 POST 使用 multipart/form-data", body_upload_limit_size: "上傳文件大小不能超過 500 MB!", condition: "條件", condition_variable: "變量,例如: ${var}", From d58990bb160ee876ca0030d02e291181262fe010 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 14 Oct 2020 12:40:50 +0800 Subject: [PATCH 02/12] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20=E4=B8=8D=E5=90=8C=E8=AF=B7=E6=B1=82=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E5=8C=BA=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/components/request/ApiRequestConfig.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/frontend/src/business/components/api/test/components/request/ApiRequestConfig.vue b/frontend/src/business/components/api/test/components/request/ApiRequestConfig.vue index f192c009cc..76d44cf4d2 100644 --- a/frontend/src/business/components/api/test/components/request/ApiRequestConfig.vue +++ b/frontend/src/business/components/api/test/components/request/ApiRequestConfig.vue @@ -9,7 +9,7 @@
{{ request.showType() }}
-
+
{{ request.showMethod() }}
@@ -85,7 +85,13 @@ export default { selected: 0, visible: false, types: RequestFactory.TYPES, - type: "" + type: "", + methodColorMap: new Map([ + ['GET', "#61AFFE"], ['POST', '#49CC90'], ['PUT', '#fca130'], + ['PATCH', '#E2EE11'], ['DELETE', '#f93e3d'], ['OPTIONS', '#0EF5DA'], + ['HEAD', '#8E58E7'], ['CONNECT', '#90AFAE'], + ['DUBBO', '#C36EEF'],['SQL', '#0AEAD4'],['TCP', '#0A52DF'], + ]) } }, @@ -156,6 +162,11 @@ export default { break; } }, + getColor(enable, method) { + if (enable) { + return this.methodColorMap.get(method); + } + }, select(request) { if (!request) { return; From 0c3b154433c05e986b7f060e05ae1175f698a353 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 14 Oct 2020 13:08:46 +0800 Subject: [PATCH 03/12] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95)?= =?UTF-8?q?:=20=E7=8E=AF=E5=A2=83=E4=B8=AD=E5=8F=98=E9=87=8F=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E5=A4=AA=E9=95=BF=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/test/components/ApiScenarioVariables.vue | 6 +++++- .../components/api/test/components/ApiVariableInput.vue | 8 ++++++-- .../components/environment/EnvironmentCommonConfig.vue | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/frontend/src/business/components/api/test/components/ApiScenarioVariables.vue b/frontend/src/business/components/api/test/components/ApiScenarioVariables.vue index 236b3b2555..3500c4145f 100644 --- a/frontend/src/business/components/api/test/components/ApiScenarioVariables.vue +++ b/frontend/src/business/components/api/test/components/ApiScenarioVariables.vue @@ -11,7 +11,7 @@ - @@ -45,6 +45,10 @@ type: Boolean, default: true }, + showCopy: { + type: Boolean, + default: true + }, }, data() { return { diff --git a/frontend/src/business/components/api/test/components/ApiVariableInput.vue b/frontend/src/business/components/api/test/components/ApiVariableInput.vue index 7d95810ed6..0cbd17338f 100644 --- a/frontend/src/business/components/api/test/components/ApiVariableInput.vue +++ b/frontend/src/business/components/api/test/components/ApiVariableInput.vue @@ -2,8 +2,8 @@
-
{{variable}}
- +
{{variable}}
+
@@ -25,6 +25,10 @@ type: Boolean, default: true }, + showCopy: { + type: Boolean, + default: true + }, }, data() { diff --git a/frontend/src/business/components/api/test/components/environment/EnvironmentCommonConfig.vue b/frontend/src/business/components/api/test/components/environment/EnvironmentCommonConfig.vue index 2dd5c442c4..3803db4ea2 100644 --- a/frontend/src/business/components/api/test/components/environment/EnvironmentCommonConfig.vue +++ b/frontend/src/business/components/api/test/components/environment/EnvironmentCommonConfig.vue @@ -3,7 +3,7 @@ {{$t('api_test.environment.globalVariable')}} - + From cccb100ed045d4b77ad9fca143dace1673c82030 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 14 Oct 2020 14:37:49 +0800 Subject: [PATCH 04/12] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20sql=20=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/dto/scenario/request/SqlRequest.java | 5 +++++ .../api/test/components/request/ApiSqlRequestForm.vue | 8 +++++++- .../components/api/test/model/ScenarioModel.js | 10 ++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/io/metersphere/api/dto/scenario/request/SqlRequest.java b/backend/src/main/java/io/metersphere/api/dto/scenario/request/SqlRequest.java index d48c75ac3a..b116326049 100644 --- a/backend/src/main/java/io/metersphere/api/dto/scenario/request/SqlRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/scenario/request/SqlRequest.java @@ -2,9 +2,12 @@ package io.metersphere.api.dto.scenario.request; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; +import io.metersphere.api.dto.scenario.KeyValue; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.List; + @EqualsAndHashCode(callSuper = true) @Data @JSONType(typeName = RequestType.SQL) @@ -25,4 +28,6 @@ public class SqlRequest extends Request { private String resultVariable; @JSONField(ordinal = 14) private String variableNames; + @JSONField(ordinal = 15) + private List variables; } diff --git a/frontend/src/business/components/api/test/components/request/ApiSqlRequestForm.vue b/frontend/src/business/components/api/test/components/request/ApiSqlRequestForm.vue index 92212cfffa..7282fe9d53 100644 --- a/frontend/src/business/components/api/test/components/request/ApiSqlRequestForm.vue +++ b/frontend/src/business/components/api/test/components/request/ApiSqlRequestForm.vue @@ -41,6 +41,10 @@ {{$t('api_test.request.debug')}} + + +
@@ -74,10 +78,12 @@ import MsDubboConsumerService from "@/business/components/api/test/components/request/dubbo/ConsumerAndService"; import MsJsr233Processor from "../processor/Jsr233Processor"; import MsCodeEdit from "../../../../common/components/MsCodeEdit"; + import MsApiScenarioVariables from "../ApiScenarioVariables"; export default { name: "MsApiSqlRequestForm", components: { + MsApiScenarioVariables, MsCodeEdit, MsJsr233Processor, MsDubboConsumerService, @@ -96,7 +102,7 @@ data() { return { - activeName: "sql", + activeName: "variables", databaseConfigsOptions: [], rules: { name: [ diff --git a/frontend/src/business/components/api/test/model/ScenarioModel.js b/frontend/src/business/components/api/test/model/ScenarioModel.js index a10d6e3c56..e98c96223f 100644 --- a/frontend/src/business/components/api/test/model/ScenarioModel.js +++ b/frontend/src/business/components/api/test/model/ScenarioModel.js @@ -477,6 +477,7 @@ export class SqlRequest extends Request { this.useEnvironment = options.useEnvironment; this.resultVariable = options.resultVariable; this.variableNames = options.variableNames; + this.variables = options.variables || []; this.debugReport = undefined; this.dataSource = options.dataSource; this.query = options.query; @@ -1127,6 +1128,7 @@ class JMXGenerator { } else if (request instanceof SqlRequest) { request.dataSource = scenario.databaseConfigMap.get(request.dataSource); sampler = new JDBCSampler(request.name || "", request); + this.addRequestVariables(sampler, request); } else if (request instanceof TCPRequest) { sampler = new TCPSampler(request.name || "", new JMXTCPRequest(request, scenario)); } @@ -1188,6 +1190,14 @@ class JMXGenerator { } } + addRequestVariables(httpSamplerProxy, request) { + let name = request.name + " Variables"; + let variables = this.filterKV(request.variables); + if (variables && variables.length > 0) { + httpSamplerProxy.put(new Arguments(name, variables)); + } + } + addScenarioCookieManager(threadGroup, scenario) { if (scenario.enableCookieShare) { threadGroup.put(new CookieManager(scenario.name)); From 79d9926e53daac7252122c074ab022f2bcdcdbb1 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 14 Oct 2020 15:06:54 +0800 Subject: [PATCH 05/12] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95)?= =?UTF-8?q?:=20sql=E8=87=AA=E5=AE=9A=E4=B9=89=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/business/components/api/test/model/ScenarioModel.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/business/components/api/test/model/ScenarioModel.js b/frontend/src/business/components/api/test/model/ScenarioModel.js index e98c96223f..099dabbebb 100644 --- a/frontend/src/business/components/api/test/model/ScenarioModel.js +++ b/frontend/src/business/components/api/test/model/ScenarioModel.js @@ -477,14 +477,14 @@ export class SqlRequest extends Request { this.useEnvironment = options.useEnvironment; this.resultVariable = options.resultVariable; this.variableNames = options.variableNames; - this.variables = options.variables || []; + this.variables = []; this.debugReport = undefined; this.dataSource = options.dataSource; this.query = options.query; // this.queryType = options.queryType; this.queryTimeout = options.queryTimeout || 60000; - this.sets({args: KeyValue, attachmentArgs: KeyValue}, options); + this.sets({args: KeyValue, attachmentArgs: KeyValue, variables: KeyValue}, options); } isValid() { @@ -1117,7 +1117,6 @@ class JMXGenerator { if (request.enable) { if (!request.isValid()) return; let sampler; - if (request instanceof DubboRequest) { sampler = new DubboSample(request.name || "", new JMXDubboRequest(request, scenario.dubboConfig)); } else if (request instanceof HttpRequest) { From b52359c0978ec6514dc03b419f871034ac956b05 Mon Sep 17 00:00:00 2001 From: BugKing Date: Wed, 14 Oct 2020 15:09:13 +0800 Subject: [PATCH 06/12] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=20readme=20?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 85c7bd0b8a..8dbea3c9e7 100755 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ v1.1.0 是 v1.0.0 之后的功能版本。 - + @@ -92,9 +92,22 @@ v1.1.0 是 v1.0.0 之后的功能版本。 + + + + - + + + + + + + + + + @@ -110,8 +123,17 @@ v1.1.0 是 v1.0.0 之后的功能版本。 - - + + + + + + + + + + + @@ -123,19 +145,56 @@ v1.1.0 是 v1.0.0 之后的功能版本。 + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + @@ -150,6 +209,16 @@ v1.1.0 是 v1.0.0 之后的功能版本。 + + + + + + + + + + @@ -164,27 +233,37 @@ v1.1.0 是 v1.0.0 之后的功能版本。 - - + + - + + + + + + + + - + + + +
测试跟踪测试跟踪 项目管理 多项目支持,测试用例、测试计划与项目关联
快速导入用例到系统
测试用例评审基于已有用例发起评审
测试计划跟踪在线更新评审结果
支持多人在线添加评审评论
灵活的评审人分配形式
测试计划跟踪 基于已有用例发起测试计划
与平台中的接口测试、性能测试功能结合,自动更新关联用例的结果
接口测试测试脚本记录测试用例关联的缺陷
缺陷记录支持关联到 Jira/TAPD 平台
测试报告支持分享、导出
接口测试测试脚本 在线编辑接口测试内容
支持多接口的场景化测试
测试场景复用
测试场景支持引用已有环境信息
测试环境信息管理
通过浏览器插件快速录制测试脚本
测试报告测试执行后自动生成测试报告支持前后置 BeanShell/Python 脚本
上传并引用自定义 Jar 包
多协议支持,支持 HTTP、Dubbo、SQL、TCP 类型请求
支持等待时间、条件判断等逻辑控制功能
测试执行内置定时任务支持
通过 Jenkins 插件触发测试执行
多个接口测试一键合并执行
一键创建性能测试
测试报告测试执行后自动生成动态实时测试报告
测试报告导出
性能测试测试脚本通过邮件、IM 工具等通知执行结果
性能测试测试脚本 完全兼容 JMeter 脚本
通过浏览器插件快速录制测试脚本
多协议支持
测试执行内置定时任务支持
通过 Jenkins 插件触发测试执行
测试报告 测试执行后自动生成测试报告查看测试日志详情
系统管理租户管理系统管理用户租户管理 支持多级租户体系
支持多种租户角色
测试资源管理LDAP 认证对接
测试资源管理 性能测试资源池管理
消息通知配置IM 工具通知(如企业微信、钉钉)
邮件通知配置
集成与扩展集成与扩展 完善的 API 列表
支持对接 Jenkins 等持续集成工具
支持对接 Jira/TAPD 等缺陷管理工具
From 16506bee0aca4b8ba51bf2a0ef9ed92d0d8543c9 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 14 Oct 2020 16:39:39 +0800 Subject: [PATCH 07/12] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95?= =?UTF-8?q?):=20=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E6=80=A7=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/ApiDatabaseController.java | 25 +++++++++++++++++++ .../api/service/APIDatabaseService.java | 23 +++++++++++++++++ .../request/database/DatabaseConfig.vue | 5 ++++ .../request/database/DatabaseFrom.vue | 9 ++++++- 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/io/metersphere/api/controller/ApiDatabaseController.java create mode 100644 backend/src/main/java/io/metersphere/api/service/APIDatabaseService.java diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiDatabaseController.java b/backend/src/main/java/io/metersphere/api/controller/ApiDatabaseController.java new file mode 100644 index 0000000000..f3b316e703 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDatabaseController.java @@ -0,0 +1,25 @@ +package io.metersphere.api.controller; + +import io.metersphere.api.dto.scenario.DatabaseConfig; +import io.metersphere.api.service.APIDatabaseService; +import io.metersphere.commons.constants.RoleConstants; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresRoles; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +@RestController +@RequestMapping(value = "/api/database") +@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR) +public class ApiDatabaseController { + + @Resource + APIDatabaseService apiDatabaseService; + + @PostMapping("/validate") + public void validate(@RequestBody DatabaseConfig databaseConfig) { + apiDatabaseService.validate(databaseConfig); + } + +} diff --git a/backend/src/main/java/io/metersphere/api/service/APIDatabaseService.java b/backend/src/main/java/io/metersphere/api/service/APIDatabaseService.java new file mode 100644 index 0000000000..939c27ff99 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/service/APIDatabaseService.java @@ -0,0 +1,23 @@ +package io.metersphere.api.service; + +import io.metersphere.api.dto.scenario.DatabaseConfig; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.LogUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.sql.DriverManager; + +@Service +@Transactional(rollbackFor = Exception.class) +public class APIDatabaseService { + + public void validate(DatabaseConfig databaseConfig) { + try { + DriverManager.getConnection(databaseConfig.getDbUrl(), databaseConfig.getUsername(), databaseConfig.getPassword()); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException(e.getMessage()); + } + } +} diff --git a/frontend/src/business/components/api/test/components/request/database/DatabaseConfig.vue b/frontend/src/business/components/api/test/components/request/database/DatabaseConfig.vue index 1dc77469b2..7542ed13df 100644 --- a/frontend/src/business/components/api/test/components/request/database/DatabaseConfig.vue +++ b/frontend/src/business/components/api/test/components/request/database/DatabaseConfig.vue @@ -27,6 +27,11 @@ currentConfig: new DatabaseConfig() } }, + watch: { + configs() { + this.currentConfig = new DatabaseConfig(); + } + }, methods: { saveConfig(config) { for (let item of this.configs) { diff --git a/frontend/src/business/components/api/test/components/request/database/DatabaseFrom.vue b/frontend/src/business/components/api/test/components/request/database/DatabaseFrom.vue index 89919ab28b..93c14e1258 100644 --- a/frontend/src/business/components/api/test/components/request/database/DatabaseFrom.vue +++ b/frontend/src/business/components/api/test/components/request/database/DatabaseFrom.vue @@ -1,5 +1,5 @@