fix(项目管理): 代码片段禁用本地执行

【【接口测试】禁用本地执行后,项目设置里的自定义代码片段未使用资源池执行】https://www.tapd.cn/55049933/bugtrace/bugs/view?bug_id=1155049933001026037

Signed-off-by: fit2-zhao <yong.zhao@fit2cloud.com>
This commit is contained in:
fit2-zhao 2023-05-09 11:54:14 +08:00 committed by fit2-zhao
parent e3b5107a53
commit 2ca7638815
7 changed files with 106 additions and 45 deletions

View File

@ -170,12 +170,12 @@ public class ApiExecuteService {
return new MsExecResponseDTO(runRequest.getTestId(), runRequest.getReportId(), runRequest.getRunMode());
}
public String getHashTree(MsJSR223Processor request) {
public HashTree getHashTree(MsJSR223Processor request) {
MsTestPlan testPlan = new MsTestPlan();
testPlan.setName(MsTestPlan.class.getCanonicalName());
testPlan.setName(request.getId());
testPlan.setHashTree(new LinkedList<>());
MsThreadGroup threadGroup = new MsThreadGroup();
threadGroup.setName(MsThreadGroup.class.getCanonicalName());
threadGroup.setName(request.getId());
threadGroup.setHashTree(new LinkedList<>());
testPlan.getHashTree().add(threadGroup);
testPlan.setProjectJarIds(NewDriverManager.getJars(new ArrayList<>() {{
@ -184,7 +184,7 @@ public class ApiExecuteService {
threadGroup.getHashTree().add(request);
ParameterConfig config = new ParameterConfig();
config.setProjectId(request.getProjectId());
return new MsTestPlan().getJmx(testPlan.generateHashTree(config));
return testPlan.generateHashTree(config);
}
private JmeterRunRequestDTO initRunRequest(RunDefinitionRequest request, List<MultipartFile> bodyFiles) {

View File

@ -8,7 +8,6 @@ import io.metersphere.api.dto.automation.ApiScenarioRequest;
import io.metersphere.api.dto.automation.TcpTreeTableDataStruct;
import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.definition.request.assertions.document.DocumentElement;
import io.metersphere.api.dto.definition.request.processors.MsJSR223Processor;
import io.metersphere.api.dto.scenario.Body;
import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult;
import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest;
@ -34,6 +33,7 @@ import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.notice.annotation.SendNotice;
import io.metersphere.request.ResetOrderRequest;
import io.metersphere.service.definition.ApiDefinitionService;
import io.metersphere.service.definition.FunctionRunService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@ -54,7 +54,8 @@ public class ApiDefinitionController {
private ExecThreadPoolExecutor execThreadPoolExecutor;
@Resource
private ApiExecuteService apiExecuteService;
@Resource
private FunctionRunService functionRunService;
@PostMapping("/list/{goPage}/{pageSize}")
@RequiresPermissions("PROJECT_API_DEFINITION:READ")
@ -392,11 +393,6 @@ public class ApiDefinitionController {
return apiDefinitionService.rawToXml(parseTreeDataDTO.getStringData());
}
@PostMapping("/get-hash-tree")
public String getHashTree(@RequestBody MsJSR223Processor request) {
return apiExecuteService.getHashTree(request);
}
@PostMapping("/update/file")
public void updateFileMetadataId(@RequestBody List<ReplaceFileIdRequest> requestList) {
apiDefinitionService.updateFileMetadataId(requestList);
@ -407,4 +403,9 @@ public class ApiDefinitionController {
public List<BaseCase> getBaseCaseByProjectId(@PathVariable String projectId) {
return apiDefinitionService.getBaseCaseByProjectId(projectId);
}
@PostMapping("/func/run")
public void run(@RequestBody Object request) {
functionRunService.run(request);
}
}

View File

@ -0,0 +1,67 @@
package io.metersphere.service.definition;
import io.metersphere.api.dto.definition.request.processors.MsJSR223Processor;
import io.metersphere.api.exec.api.ApiExecuteService;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.GenerateHashTreeUtil;
import io.metersphere.commons.utils.JSON;
import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.jmeter.ProjectClassLoader;
import io.metersphere.service.SystemParameterService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.jorphan.collections.HashTree;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
/**
* @author lyh
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class FunctionRunService {
@Resource
private ApiExecuteService apiExecuteService;
@Resource
private JMeterService jMeterService;
@Resource
private SystemParameterService systemParameterService;
public void run(Object req) {
MsJSR223Processor request = JSON.parseObject(JSON.toJSONString(req), MsJSR223Processor.class);
// 验证是否本地执行
RunModeConfigDTO runModeConfigDTO = new RunModeConfigDTO();
jMeterService.verifyPool(request.getProjectId(), runModeConfigDTO);
try {
HashTree hashTree = apiExecuteService.getHashTree(request);
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(),
request.getId(), ApiRunMode.DEBUG.name(), TriggerMode.MANUAL.name(), hashTree);
runRequest.setDebug(true);
if (StringUtils.isNotEmpty(runModeConfigDTO.getResourcePoolId())) {
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(runModeConfigDTO.getResourcePoolId()));
runRequest.setPoolId(runModeConfigDTO.getResourcePoolId());
BaseSystemConfigDTO baseInfo = systemParameterService.getBaseInfo();
runRequest.setPlatformUrl(GenerateHashTreeUtil.getPlatformUrl(baseInfo, runRequest, null));
} else {
// 加载自定义JAR
ClassLoader loader = ProjectClassLoader.getClassLoader(new ArrayList<>() {{
this.add(request.getProjectId());
}});
Thread.currentThread().setContextClassLoader(loader);
}
// 开始执行
jMeterService.run(runRequest);
} catch (Exception e) {
MSException.throwException(e.getMessage());
}
}
}

View File

@ -7,11 +7,10 @@ import io.metersphere.base.domain.CustomFunctionWithBLOBs;
import io.metersphere.code.snippet.service.CustomFunctionService;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.request.CustomFunctionRequest;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import java.util.List;
/**
@ -56,8 +55,8 @@ public class CustomFunctionController {
return customFunctionService.get(id);
}
@PostMapping("/run/{reportId}")
public MsExecResponseDTO run(@PathVariable String reportId, @RequestBody Object request) {
return customFunctionService.run(reportId, request);
@PostMapping("/run")
public void run(@RequestBody Object request) {
customFunctionService.run(request);
}
}

View File

@ -6,17 +6,17 @@ import io.metersphere.base.mapper.CustomFunctionMapper;
import io.metersphere.base.mapper.FileMetadataMapper;
import io.metersphere.base.mapper.ext.ExtCustomFunctionMapper;
import io.metersphere.code.snippet.listener.MsDebugListener;
import io.metersphere.code.snippet.util.FixedCapacityUtils;
import io.metersphere.code.snippet.util.ProjectFileUtils;
import io.metersphere.commons.constants.MicroServiceName;
import io.metersphere.commons.constants.StorageConstants;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.FileUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.constants.BackendListenerConstants;
import io.metersphere.dto.FileInfoDTO;
import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.dto.ProjectJarConfig;
import io.metersphere.jmeter.LocalRunner;
import io.metersphere.jmeter.ProjectClassLoader;
import io.metersphere.metadata.service.FileMetadataService;
import io.metersphere.request.CustomFunctionRequest;
@ -35,10 +35,8 @@ import org.apache.jorphan.collections.HashTree;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -204,25 +202,8 @@ public class CustomFunctionService {
return jarConfigMap;
}
public MsExecResponseDTO run(String reportId, Object request) {
HashTree hashTree = null;
//下载项目执行代码片段的jar包
getJars();
String jmx = microService.postForData(MicroServiceName.API_TEST, "/api/definition/get-hash-tree", request, String.class);
try {
Object scriptWrapper = SaveService.loadElement(new ByteArrayInputStream(jmx.getBytes(StandardCharsets.UTF_8)));
hashTree = this.getHashTree(scriptWrapper);
} catch (Exception e) {
LogUtil.error(e.getMessage());
MSException.throwException(e.getMessage());
}
if (!FixedCapacityUtils.containsKey(reportId)) {
FixedCapacityUtils.put(reportId,new StringBuffer());
}
addDebugListener(reportId, hashTree);
LocalRunner runner = new LocalRunner(hashTree);
runner.run(reportId);
return null;
public void run(Object request) {
microService.postForData(MicroServiceName.API_TEST, "/api/definition/func/run", request);
}
private HashTree getHashTree(Object scriptWrapper) throws Exception {

View File

@ -24,10 +24,20 @@ export function modifyCodeSnippet(obj) {
return post('/custom/func/update', obj);
}
export function runCodeSnippet(reportId, param) {
return post(`/custom/func/run/${reportId}`, param);
export function runCodeSnippet( param) {
return post(`/custom/func/run`, param);
}
export const apiSocket = (url) => {
let protocol = "ws://";
if (window.location.protocol === 'https:') {
protocol = "wss://";
}
let uri = protocol + window.location.host + url;
return new WebSocket(uri);
};
export function getSocket(reportId) {
return socket(`/websocket/${reportId}`)
return apiSocket(`/api/websocket/${reportId}`)
}

View File

@ -3,6 +3,7 @@
</template>
<script>
import {getSocket, runCodeSnippet} from "../../../api/custom-func";
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
export default {
name: 'FunctionRun',
@ -59,7 +60,9 @@ export default {
this.websocket.onopen = this.onOpen;
},
run() {
runCodeSnippet(this.reportId, this.runData).then(res => {
this.runData.id = this.reportId;
this.runData.projectId = getCurrentProjectID();
runCodeSnippet(this.runData).then(res => {
this.requestResult = res.data;
}).catch(() => {
this.$emit('errorRefresh', {});