diff --git a/backend/src/main/java/io/metersphere/api/controller/APIReportController.java b/backend/src/main/java/io/metersphere/api/controller/APIReportController.java index aaae01caec..de08c89c3a 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APIReportController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APIReportController.java @@ -43,9 +43,9 @@ public class APIReportController { return PageUtils.setPageInfo(page, apiReportService.list(request)); } - @GetMapping("/get/{testId}") - public ApiTestReport get(@PathVariable String testId) { - return apiReportService.get(testId); + @GetMapping("/get/{reportId}") + public APIReportResult get(@PathVariable String reportId) { + return apiReportService.get(reportId); } @PostMapping("/delete") diff --git a/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java b/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java index 0a90a617e5..a350d85a6d 100644 --- a/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java +++ b/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java @@ -9,5 +9,7 @@ import lombok.Setter; @Getter public class APIReportResult extends ApiTestReport { + private String testName; + private String projectName; } 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 caba502e8c..483f711dbe 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -93,7 +93,8 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl } RequestResult requestResult = getRequestResult(result); - scenarioResult.getRequestResult().add(requestResult); + scenarioResult.getRequestResults().add(requestResult); + scenarioResult.addResponseTime(result.getTime()); testResult.addPassAssertions(requestResult.getPassAssertions()); testResult.addTotalAssertions(requestResult.getTotalAssertions()); @@ -110,14 +111,18 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl } private RequestResult getRequestResult(SampleResult result) { + String body = result.getSamplerData(); + String method = StringUtils.substringBefore(body, " "); + RequestResult requestResult = new RequestResult(); requestResult.setName(result.getSampleLabel()); requestResult.setUrl(result.getUrlAsString()); - requestResult.setSuccess(result.isSuccessful()); - requestResult.setBody(result.getSamplerData()); + requestResult.setMethod(method); + requestResult.setBody(body); requestResult.setHeaders(result.getRequestHeaders()); requestResult.setRequestSize(result.getSentBytes()); requestResult.setTotalAssertions(result.getAssertionResults().length); + requestResult.setSuccess(result.isSuccessful()); ResponseResult responseResult = requestResult.getResponseResult(); responseResult.setBody(result.getResponseDataAsString()); diff --git a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java index 147ac67d16..818ebc2922 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java @@ -1,21 +1,31 @@ package io.metersphere.api.jmeter; import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.CommonBeanFactory; +import io.metersphere.config.JmeterProperties; import io.metersphere.i18n.Translator; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.collections.HashTree; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Service; import java.io.InputStream; import java.lang.reflect.Field; +import javax.annotation.Resource; + @Service public class JMeterService { + @Resource + private JmeterProperties jmeterProperties; + public void run(InputStream is) { - JMeterUtils.loadJMeterProperties("/Users/q4speed/Downloads/apache-jmeter-5.2.1/bin/jmeter.properties"); - JMeterUtils.setJMeterHome("/Users/q4speed/Downloads/apache-jmeter-5.2.1"); + String JMETER_HOME = jmeterProperties.getHome(); + String JMETER_PROPERTIES = JMETER_HOME + "/bin/jmeter.properties"; + JMeterUtils.loadJMeterProperties(JMETER_PROPERTIES); + JMeterUtils.setJMeterHome(JMETER_HOME); try { Object scriptWrapper = SaveService.loadElement(is); HashTree testPlan = getHashTree(scriptWrapper); diff --git a/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java b/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java index e440a74d70..cc9d42bff3 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java @@ -9,6 +9,8 @@ public class RequestResult { private String url; + private String method; + private long requestSize; private boolean success; diff --git a/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java b/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java index e61ac8f029..0224d42919 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java @@ -22,7 +22,11 @@ public class ScenarioResult { private int passAssertions = 0; - private final List requestResult = new ArrayList<>(); + private final List requestResults = new ArrayList<>(); + + public void addResponseTime(long time) { + this.responseTime += time; + } public void addError() { this.error++; diff --git a/backend/src/main/java/io/metersphere/api/service/APIReportService.java b/backend/src/main/java/io/metersphere/api/service/APIReportService.java index 5ef76196bc..03a7dd495a 100644 --- a/backend/src/main/java/io/metersphere/api/service/APIReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/APIReportService.java @@ -38,8 +38,8 @@ public class APIReportService { return extApiTestReportMapper.list(request); } - public ApiTestReport get(String id) { - return apiTestReportMapper.selectByPrimaryKey(id); + public APIReportResult get(String reportId) { + return extApiTestReportMapper.get(reportId); } public List listByTestId(String testId) { diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.java index 3d6cbd4cb5..c03c871e5f 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.java @@ -13,4 +13,6 @@ public interface ExtApiTestReportMapper { List listByTestId(@Param("testId") String testId); + APIReportResult get(@Param("id") String id); + } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml index 0e0b8a0430..e518f862c8 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestReportMapper.xml @@ -4,12 +4,13 @@ + + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/config/JmeterProperties.java b/backend/src/main/java/io/metersphere/config/JmeterProperties.java index 5621c4c247..bfe302b5fd 100644 --- a/backend/src/main/java/io/metersphere/config/JmeterProperties.java +++ b/backend/src/main/java/io/metersphere/config/JmeterProperties.java @@ -1,20 +1,19 @@ package io.metersphere.config; +import lombok.Getter; +import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = JmeterProperties.JMETER_PREFIX) +@Setter +@Getter public class JmeterProperties { public static final String JMETER_PREFIX = "jmeter"; private String image; - public String getImage() { - return image; - } + private String home; - public void setImage(String image) { - this.image = image; - } } diff --git a/backend/src/main/java/io/metersphere/config/KafkaProperties.java b/backend/src/main/java/io/metersphere/config/KafkaProperties.java index c0036f475c..912352b24b 100644 --- a/backend/src/main/java/io/metersphere/config/KafkaProperties.java +++ b/backend/src/main/java/io/metersphere/config/KafkaProperties.java @@ -1,8 +1,12 @@ package io.metersphere.config; +import lombok.Getter; +import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = KafkaProperties.KAFKA_PREFIX) +@Getter +@Setter public class KafkaProperties { public static final String KAFKA_PREFIX = "kafka"; @@ -22,112 +26,8 @@ public class KafkaProperties { private KafkaProperties.Ssl ssl = new KafkaProperties.Ssl(); private KafkaProperties.Log log = new KafkaProperties.Log(); - public String getAcks() { - return acks; - } - - public void setAcks(String acks) { - this.acks = acks; - } - - public String getTopic() { - return topic; - } - - public void setTopic(String topic) { - this.topic = topic; - } - - public String getFields() { - return fields; - } - - public void setFields(String fields) { - this.fields = fields; - } - - public String getTimestamp() { - return timestamp; - } - - public void setTimestamp(String timestamp) { - this.timestamp = timestamp; - } - - public String getBootstrapServers() { - return bootstrapServers; - } - - public void setBootstrapServers(String bootstrapServers) { - this.bootstrapServers = bootstrapServers; - } - - public String getSampleFilter() { - return sampleFilter; - } - - public void setSampleFilter(String sampleFilter) { - this.sampleFilter = sampleFilter; - } - - public String getTestMode() { - return testMode; - } - - public void setTestMode(String testMode) { - this.testMode = testMode; - } - - - public String getCompressionType() { - return compressionType; - } - - public void setCompressionType(String compressionType) { - this.compressionType = compressionType; - } - - - public String getClientId() { - return clientId; - } - - public void setClientId(String clientId) { - this.clientId = clientId; - } - - public String getParseAllReqHeaders() { - return parseAllReqHeaders; - } - - public void setParseAllReqHeaders(String parseAllReqHeaders) { - this.parseAllReqHeaders = parseAllReqHeaders; - } - - public String getParseAllResHeaders() { - return parseAllResHeaders; - } - - public void setParseAllResHeaders(String parseAllResHeaders) { - this.parseAllResHeaders = parseAllResHeaders; - } - - public String getBatchSize() { - return batchSize; - } - - public void setBatchSize(String batchSize) { - this.batchSize = batchSize; - } - - public String getConnectionsMaxIdleMs() { - return connectionsMaxIdleMs; - } - - public void setConnectionsMaxIdleMs(String connectionsMaxIdleMs) { - this.connectionsMaxIdleMs = connectionsMaxIdleMs; - } - + @Getter + @Setter public static class Ssl { private String enabled = "false"; private String keyPassword; @@ -140,124 +40,11 @@ public class KafkaProperties { private String protocol; private String enabledProtocols; private String provider; - - public Ssl() { - } - - public String getEnabled() { - return enabled; - } - - public void setEnabled(String enabled) { - this.enabled = enabled; - } - - public String getKeyPassword() { - return keyPassword; - } - - public void setKeyPassword(String keyPassword) { - this.keyPassword = keyPassword; - } - - public String getKeystoreLocation() { - return keystoreLocation; - } - - public void setKeystoreLocation(String keystoreLocation) { - this.keystoreLocation = keystoreLocation; - } - - public String getKeystorePassword() { - return keystorePassword; - } - - public void setKeystorePassword(String keystorePassword) { - this.keystorePassword = keystorePassword; - } - - public String getKeystoreType() { - return keystoreType; - } - - public void setKeystoreType(String keystoreType) { - this.keystoreType = keystoreType; - } - - public String getTruststoreLocation() { - return truststoreLocation; - } - - public void setTruststoreLocation(String truststoreLocation) { - this.truststoreLocation = truststoreLocation; - } - - public String getTruststorePassword() { - return truststorePassword; - } - - public void setTruststorePassword(String truststorePassword) { - this.truststorePassword = truststorePassword; - } - - public String getTruststoreType() { - return truststoreType; - } - - public void setTruststoreType(String truststoreType) { - this.truststoreType = truststoreType; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getEnabledProtocols() { - return enabledProtocols; - } - - public void setEnabledProtocols(String enabledProtocols) { - this.enabledProtocols = enabledProtocols; - } - - public String getProvider() { - return provider; - } - - public void setProvider(String provider) { - this.provider = provider; - } - } - - public Ssl getSsl() { - return ssl; - } - - public void setSsl(Ssl ssl) { - this.ssl = ssl; } + @Getter + @Setter public static class Log { private String topic; - - public String getTopic() { - return topic; - } - - public void setTopic(String topic) { - this.topic = topic; - } - } - - public Log getLog() { - return log; - } - - public void setLog(Log log) { - this.log = log; } } diff --git a/backend/src/main/java/io/metersphere/controller/UserController.java b/backend/src/main/java/io/metersphere/controller/UserController.java index 8c38b04282..4d2a968141 100644 --- a/backend/src/main/java/io/metersphere/controller/UserController.java +++ b/backend/src/main/java/io/metersphere/controller/UserController.java @@ -4,6 +4,7 @@ import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.base.domain.User; import io.metersphere.commons.constants.RoleConstants; +import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; import io.metersphere.controller.request.UserRequest; @@ -17,6 +18,7 @@ import io.metersphere.service.UserService; import io.metersphere.service.WorkspaceService; import io.metersphere.user.SessionUser; import io.metersphere.user.SessionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.beans.BeanUtils; @@ -120,6 +122,9 @@ public class UserController { @PostMapping("/update/current") public UserDTO updateCurrentUser(@RequestBody User user) { + UserDTO userDTO = userService.getUserDTO(user.getId()); + BeanUtils.copyProperties(user, userDTO); + SessionUtils.putUser(SessionUser.fromUser(userDTO)); userService.updateUser(user); return SessionUtils.getUser(); } @@ -182,6 +187,10 @@ public class UserController { @RequiresRoles(value = {RoleConstants.TEST_MANAGER,RoleConstants.ORG_ADMIN}, logical = Logical.OR) public void deleteMember(@PathVariable String workspaceId, @PathVariable String userId) { workspaceService.checkWorkspaceOwner(workspaceId); + String currentUserId = SessionUtils.getUser().getId(); + if (StringUtils.equals(userId, currentUserId)) { + MSException.throwException("Insufficient permissions!"); + } userService.deleteMember(workspaceId, userId); } @@ -202,6 +211,10 @@ public class UserController { @RequiresRoles(RoleConstants.ORG_ADMIN) public void delOrganizationMember(@PathVariable String organizationId, @PathVariable String userId) { organizationService.checkOrgOwner(organizationId); + String currentUserId = SessionUtils.getUser().getId(); + if (StringUtils.equals(userId, currentUserId)) { + MSException.throwException("Insufficient permissions!"); + } userService.delOrganizationMember(organizationId, userId); } diff --git a/backend/src/main/java/io/metersphere/service/UserService.java b/backend/src/main/java/io/metersphere/service/UserService.java index 120a2afa4e..b40f1c4869 100644 --- a/backend/src/main/java/io/metersphere/service/UserService.java +++ b/backend/src/main/java/io/metersphere/service/UserService.java @@ -124,11 +124,8 @@ public class UserService { } public void updateUser(User user) { - UserDTO userDTO = getUserDTO(user.getId()); - BeanUtils.copyProperties(user, userDTO); // MD5 user.setPassword(CodingUtil.md5(user.getPassword())); - SessionUtils.putUser(SessionUser.fromUser(userDTO)); user.setUpdateTime(System.currentTimeMillis()); userMapper.updateByPrimaryKeySelective(user); } diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 2805932dce..671b65f503 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -63,4 +63,5 @@ kafka.ssl.provider= kafka.ssl.truststore-type= # jmeter -jmeter.image=registry.fit2cloud.com/metersphere/jmeter-master:0.0.4 \ No newline at end of file +jmeter.image=registry.fit2cloud.com/metersphere/jmeter-master:0.0.4 +jmeter.home=/opt/jmeter/apache-jmeter-5.2.1 \ No newline at end of file diff --git a/frontend/src/business/components/api/head/ApiHeaderMenus.vue b/frontend/src/business/components/api/head/ApiHeaderMenus.vue index a13259966d..fa9af5ac37 100644 --- a/frontend/src/business/components/api/head/ApiHeaderMenus.vue +++ b/frontend/src/business/components/api/head/ApiHeaderMenus.vue @@ -23,8 +23,8 @@ - - + + - + @@ -90,7 +90,7 @@ title: this.$t('report.recent'), url: "/api/report/recent/5", index: function (item) { - return '/api/report/view?id=' + item.id; + return '/api/report/view/' + item.id; } } } diff --git a/frontend/src/business/components/api/report/ApiReportList.vue b/frontend/src/business/components/api/report/ApiReportList.vue index 791b19d2e8..365a6fdb7f 100644 --- a/frontend/src/business/components/api/report/ApiReportList.vue +++ b/frontend/src/business/components/api/report/ApiReportList.vue @@ -32,6 +32,38 @@ {{ scope.row.updateTime | timestampFormatDate }} + + + @@ -101,7 +133,7 @@ }) }, handleDelete(report) { - this.$alert(this.$t('load_test.delete_confirm') + report.name + "?", '', { + this.$alert(this.$t('api_report.delete_confirm') + report.name + "?", '', { confirmButtonText: this.$t('commons.confirm'), callback: (action) => { if (action === 'confirm') { diff --git a/frontend/src/business/components/api/report/ApiReportView.vue b/frontend/src/business/components/api/report/ApiReportView.vue index bfc05d03b9..5c6116460f 100644 --- a/frontend/src/business/components/api/report/ApiReportView.vue +++ b/frontend/src/business/components/api/report/ApiReportView.vue @@ -1,117 +1,113 @@ diff --git a/frontend/src/business/components/api/report/components/AssertionResults.vue b/frontend/src/business/components/api/report/components/AssertionResults.vue new file mode 100644 index 0000000000..e540791885 --- /dev/null +++ b/frontend/src/business/components/api/report/components/AssertionResults.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/frontend/src/business/components/api/report/components/MetricChart.vue b/frontend/src/business/components/api/report/components/MetricChart.vue new file mode 100644 index 0000000000..baafe76138 --- /dev/null +++ b/frontend/src/business/components/api/report/components/MetricChart.vue @@ -0,0 +1,202 @@ + + + + + diff --git a/frontend/src/business/components/api/report/components/RequestMetric.vue b/frontend/src/business/components/api/report/components/RequestMetric.vue new file mode 100644 index 0000000000..1ebfa0e203 --- /dev/null +++ b/frontend/src/business/components/api/report/components/RequestMetric.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/frontend/src/business/components/api/report/components/RequestResult.vue b/frontend/src/business/components/api/report/components/RequestResult.vue new file mode 100644 index 0000000000..1dc58836a4 --- /dev/null +++ b/frontend/src/business/components/api/report/components/RequestResult.vue @@ -0,0 +1,122 @@ + + + + + diff --git a/frontend/src/business/components/api/report/components/RequestText.vue b/frontend/src/business/components/api/report/components/RequestText.vue new file mode 100644 index 0000000000..60da170d46 --- /dev/null +++ b/frontend/src/business/components/api/report/components/RequestText.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/frontend/src/business/components/api/report/components/ResponseText.vue b/frontend/src/business/components/api/report/components/ResponseText.vue new file mode 100644 index 0000000000..f711aad3bc --- /dev/null +++ b/frontend/src/business/components/api/report/components/ResponseText.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/frontend/src/business/components/api/report/components/ScenarioResult.vue b/frontend/src/business/components/api/report/components/ScenarioResult.vue new file mode 100644 index 0000000000..8e5bb9b034 --- /dev/null +++ b/frontend/src/business/components/api/report/components/ScenarioResult.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/frontend/src/business/components/api/test/ApiTestList.vue b/frontend/src/business/components/api/test/ApiTestList.vue index 9506a556a1..a6a5699289 100644 --- a/frontend/src/business/components/api/test/ApiTestList.vue +++ b/frontend/src/business/components/api/test/ApiTestList.vue @@ -38,12 +38,43 @@ {{ scope.row.updateTime | timestampFormatDate }} + + + @@ -57,9 +88,10 @@