refactor: ESB功能优化-ESB接口测试,使用ESB数据格式展现
ESB功能优化-测试ESB接口时使用ESB数据格式展现
This commit is contained in:
parent
52143b1894
commit
4f937f9d11
|
@ -16,6 +16,7 @@ import io.metersphere.api.service.ApiTestEnvironmentService;
|
|||
import io.metersphere.api.service.EsbApiParamService;
|
||||
import io.metersphere.api.service.EsbImportService;
|
||||
import io.metersphere.base.domain.ApiDefinition;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
|
@ -100,9 +101,9 @@ public class ApiDefinitionController {
|
|||
|
||||
@PostMapping(value = "/update", consumes = {"multipart/form-data"})
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR)
|
||||
public void update(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||
public ApiDefinitionWithBLOBs update(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||
checkPermissionService.checkProjectOwner(request.getProjectId());
|
||||
apiDefinitionService.update(request, bodyFiles);
|
||||
return apiDefinitionService.update(request, bodyFiles);
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{id}")
|
||||
|
|
|
@ -173,7 +173,7 @@ public class ApiDefinitionService {
|
|||
FileUtils.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||
}
|
||||
|
||||
public void update(SaveApiDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
||||
public ApiDefinitionWithBLOBs update(SaveApiDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
||||
if (request.getRequest() != null) {
|
||||
deleteFileByTestId(request.getRequest().getId());
|
||||
}
|
||||
|
@ -182,8 +182,9 @@ public class ApiDefinitionService {
|
|||
if (StringUtils.equals(request.getProtocol(), "DUBBO")) {
|
||||
request.setMethod("dubbo://");
|
||||
}
|
||||
updateTest(request);
|
||||
ApiDefinitionWithBLOBs returnModel = updateTest(request);
|
||||
FileUtils.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||
return returnModel;
|
||||
}
|
||||
|
||||
public void delete(String apiId) {
|
||||
|
@ -274,7 +275,7 @@ public class ApiDefinitionService {
|
|||
|
||||
}
|
||||
|
||||
private ApiDefinition updateTest(SaveApiDefinitionRequest request) {
|
||||
private ApiDefinitionWithBLOBs updateTest(SaveApiDefinitionRequest request) {
|
||||
checkNameExist(request);
|
||||
if (StringUtils.equals(request.getMethod(), "ESB")) {
|
||||
//ESB的接口类型数据,采用TCP方式去发送。并将方法类型改为TCP。 并修改发送数据
|
||||
|
@ -546,6 +547,8 @@ public class ApiDefinitionService {
|
|||
* @return
|
||||
*/
|
||||
public String run(RunDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
||||
//检查是否是ESB请求:ESB请求需要根据数据结构更换参数
|
||||
request = esbApiParamService.checkIsEsbRequest(request);
|
||||
int count = 100;
|
||||
BaseSystemConfigDTO dto = systemParameterService.getBaseInfo();
|
||||
if (StringUtils.isNotEmpty(dto.getConcurrency())) {
|
||||
|
|
|
@ -5,17 +5,16 @@ import com.alibaba.fastjson.JSONObject;
|
|||
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.ApiDefinitionResult;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseResult;
|
||||
import io.metersphere.api.dto.definition.SaveApiDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.SaveApiTestCaseRequest;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.definition.request.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;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.EsbApiParamsExample;
|
||||
import io.metersphere.base.domain.EsbApiParamsWithBLOBs;
|
||||
import io.metersphere.base.mapper.EsbApiParamsMapper;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -400,4 +399,33 @@ public class EsbApiParamService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RunDefinitionRequest checkIsEsbRequest(RunDefinitionRequest request) {
|
||||
try {
|
||||
//修改reqeust.parameters
|
||||
//用户交互感受:ESB的发送数据以报文模板为主框架,同时前端不再有key-value的表格数据填充。
|
||||
//业务逻辑: 发送ESB接口数据时,使用报文模板中的数据,同时报文模板中的${取值}目的是为了拼接数据结构(比如xml的子节点)
|
||||
//代码实现: 此处打算解析前端传来的EsbDataStruct数据结构,将数据结构按照报文模板中的${取值}为最高优先级组装keyValue对象。这样Jmeter会自动拼装为合适的xml
|
||||
if(request.getTestElement() != null ){
|
||||
MsTestPlan testPlan = (MsTestPlan) request.getTestElement();
|
||||
if(CollectionUtils.isNotEmpty(testPlan.getHashTree())){
|
||||
for (MsTestElement testElement: testPlan.getHashTree()) {
|
||||
if(CollectionUtils.isNotEmpty(testElement.getHashTree())){
|
||||
for (MsTestElement apiElement:testElement.getHashTree()) {
|
||||
if(apiElement instanceof MsTCPSampler){
|
||||
MsTCPSampler tcpSampler = (MsTCPSampler) apiElement;
|
||||
tcpSampler.setProtocol("ESB");
|
||||
List<KeyValue> keyValueList = this.genKeyValueListByDataStruct(tcpSampler, tcpSampler.getEsbDataStruct());
|
||||
tcpSampler.setParameters(keyValueList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@
|
|||
selectDataRange: 'all',
|
||||
showCasePage: true,
|
||||
apiDefaultTab: 'default',
|
||||
currentProtocol: null,
|
||||
currentProtocol: 'HTTP',
|
||||
currentModule: null,
|
||||
selectNodeIds: [],
|
||||
currentApi: {},
|
||||
|
@ -260,7 +260,7 @@
|
|||
});
|
||||
},
|
||||
'$route'(to, from) { // 路由改变时,把接口定义界面中的 ctrl s 保存快捷键监听移除
|
||||
if (to.path.indexOf('/api/definition') == -1) {
|
||||
if (to.path.indexOf('/api/definition') === -1) {
|
||||
if (this.$refs && this.$refs.apiConfig) {
|
||||
this.$refs.apiConfig.forEach(item => {
|
||||
item.removeListener();
|
||||
|
@ -299,7 +299,7 @@
|
|||
}); // 删除所有tab的 ctrl + s 监听
|
||||
let tabs = this.apiTabs;
|
||||
let index = tabs.findIndex(item => item.name === tab.name); // 找到当前选中tab的index
|
||||
if (index != -1 && this.$refs.apiConfig[index - 1]) {
|
||||
if (index !== -1 && this.$refs.apiConfig[index - 1]) {
|
||||
this.$refs.apiConfig[index - 1].addListener(); // 为选中tab添加 ctrl + s 监听(index-1的原因是要除去第一个固有tab)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,9 +101,11 @@ export default {
|
|||
runTest(data) {
|
||||
this.setParameters(data);
|
||||
let bodyFiles = this.getBodyUploadFiles(data);
|
||||
this.$fileUpload(this.reqUrl, null, bodyFiles, data, () => {
|
||||
this.$fileUpload(this.reqUrl, null, bodyFiles, data, response => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.reqUrl = "/api/definition/update";
|
||||
let newData = response.data;
|
||||
data.request = JSON.parse(newData.request);
|
||||
this.$emit('runTest', data);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -26,19 +26,32 @@
|
|||
<environment-select :type="'TCP'" :current-data="api" :project-id="projectId"/>
|
||||
</el-form-item>
|
||||
|
||||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
<!-- TCP 请求参数 -->
|
||||
<ms-basis-parameters :request="api.request" @callback="runTest" ref="requestForm"/>
|
||||
|
||||
<!-- TCP 请求参数 -->
|
||||
<!-- <p class="tip">{{$t('api_test.definition.request.req_param')}} </p>-->
|
||||
<!-- <ms-basis-parameters :request="api.request" @callback="runTest" ref="requestForm"/>-->
|
||||
|
||||
<div v-if="api.method=='TCP'">
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<ms-basis-parameters :request="api.request" @callback="runTest" ref="requestForm"/>
|
||||
<!--返回结果-->
|
||||
<!-- HTTP 请求返回数据 -->
|
||||
<p class="tip">{{$t('api_test.definition.request.res_param')}} </p>
|
||||
<ms-request-result-tail :response="responseData" ref="runResult"/>
|
||||
</div>
|
||||
<div v-else-if="api.method=='ESB'">
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<esb-definition v-xpack v-if="showXpackCompnent" :show-script="true" :request="api.request" @callback="runTest" ref="requestForm"/>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<!--返回结果-->
|
||||
<!-- HTTP 请求返回数据 -->
|
||||
<p class="tip">{{$t('api_test.definition.request.res_param')}} </p>
|
||||
<ms-request-result-tail :response="responseData" ref="runResult"/>
|
||||
|
||||
<ms-jmx-step :request="api.request" :response="responseData"/>
|
||||
|
||||
<div v-if="api.method=='ESB'">
|
||||
<p class="tip">{{$t('api_test.definition.request.res_param')}}</p>
|
||||
<esb-definition-response v-xpack v-if="showXpackCompnent" :is-api-component="false" :show-options-button="false" :request="api.request" :response-data="responseData" />
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
|
@ -65,7 +78,9 @@ import MsBasisParameters from "../request/tcp/TcpBasisParameters";
|
|||
import {REQ_METHOD} from "../../model/JsonData";
|
||||
import EnvironmentSelect from "../environment/EnvironmentSelect";
|
||||
import MsJmxStep from "../step/JmxStep";
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const esbDefinition = (requireComponent!=null&&requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {};
|
||||
const esbDefinitionResponse = (requireComponent!=null&&requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {};
|
||||
export default {
|
||||
name: "RunTestTCPPage",
|
||||
components: {
|
||||
|
@ -77,168 +92,178 @@ export default {
|
|||
MsBottomContainer,
|
||||
MsRequestResultTail,
|
||||
MsRun,
|
||||
MsBasisParameters
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
api: {},
|
||||
loaded: false,
|
||||
loading: false,
|
||||
currentRequest: {},
|
||||
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
|
||||
reqOptions: REQ_METHOD,
|
||||
environments: [],
|
||||
refreshSign: "",
|
||||
createCase: "",
|
||||
rules: {
|
||||
environmentId: [{required: true, message: this.$t('api_test.definition.request.run_env'), trigger: 'change'}],
|
||||
},
|
||||
runData: [],
|
||||
reportId: "",
|
||||
MsBasisParameters,
|
||||
"esbDefinition": esbDefinition.default,
|
||||
"esbDefinitionResponse": esbDefinitionResponse.default
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
api: {},
|
||||
loaded: false,
|
||||
loading: false,
|
||||
currentRequest: {},
|
||||
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
|
||||
reqOptions: REQ_METHOD,
|
||||
environments: [],
|
||||
refreshSign: "",
|
||||
createCase: "",
|
||||
rules: {
|
||||
environmentId: [{required: true, message: this.$t('api_test.definition.request.run_env'), trigger: 'change'}],
|
||||
},
|
||||
runData: [],
|
||||
reportId: "",
|
||||
showXpackCompnent:false,
|
||||
}
|
||||
},
|
||||
props: {apiData: {}, currentProtocol: String,syncTabs: Array, projectId: String},
|
||||
methods: {
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "load_case":
|
||||
return this.loadCase();
|
||||
case "save_as_case":
|
||||
return this.saveAsCase();
|
||||
case "update_api":
|
||||
return this.updateApi();
|
||||
case "save_as_api":
|
||||
return this.saveAsApi();
|
||||
default:
|
||||
return this.$refs['requestForm'].validate();
|
||||
}
|
||||
},
|
||||
props: {apiData: {}, currentProtocol: String,syncTabs: Array, projectId: String},
|
||||
methods: {
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "load_case":
|
||||
return this.loadCase();
|
||||
case "save_as_case":
|
||||
return this.saveAsCase();
|
||||
case "update_api":
|
||||
return this.updateApi();
|
||||
case "save_as_api":
|
||||
return this.saveAsApi();
|
||||
default:
|
||||
return this.$refs['requestForm'].validate();
|
||||
refresh(){
|
||||
this.$emit('refresh');
|
||||
},
|
||||
runTest() {
|
||||
this.$refs['apiData'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.runData = [];
|
||||
this.runData.push(this.api.request);
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
}
|
||||
},
|
||||
refresh(){
|
||||
this.$emit('refresh');
|
||||
},
|
||||
runTest() {
|
||||
this.$refs['apiData'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.runData = [];
|
||||
this.runData.push(this.api.request);
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
}
|
||||
})
|
||||
},
|
||||
runRefresh(data) {
|
||||
this.responseData = data;
|
||||
this.loading = false;
|
||||
},
|
||||
saveAs() {
|
||||
this.$emit('saveAs', this.api);
|
||||
},
|
||||
loadCase() {
|
||||
this.refreshSign = getUUID();
|
||||
this.$refs.caseList.open();
|
||||
this.visible = true;
|
||||
},
|
||||
apiCaseClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.api.bodyUploadIds = [];
|
||||
let request = this.api.request;
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.api.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
saveAsCase() {
|
||||
this.createCase = getUUID();
|
||||
this.$refs.caseList.open();
|
||||
this.loaded = false;
|
||||
},
|
||||
saveAsApi() {
|
||||
let data = {};
|
||||
let req = this.api.request;
|
||||
req.id = getUUID();
|
||||
data.request = JSON.stringify(req);
|
||||
data.method = this.api.method;
|
||||
data.status = this.api.status;
|
||||
data.userId = this.api.userId;
|
||||
data.description = this.api.description;
|
||||
this.$emit('saveAsApi', data);
|
||||
this.$emit('refresh');
|
||||
},
|
||||
updateApi() {
|
||||
let url = "/api/definition/update";
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
this.$fileUpload(url, null, bodyFiles, this.api, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.syncTabs.indexOf(this.api.id) === -1) {
|
||||
this.syncTabs.push(this.api.id);
|
||||
}
|
||||
this.$emit('saveApi', this.api);
|
||||
});
|
||||
},
|
||||
selectTestCase(item) {
|
||||
if (item != null) {
|
||||
this.api.request = item.request;
|
||||
} else {
|
||||
this.api.request = this.currentRequest;
|
||||
}
|
||||
},
|
||||
getResult() {
|
||||
let url = "/api/definition/report/getReport/" + this.api.id;
|
||||
this.$get(url, response => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data.content);
|
||||
this.responseData = data;
|
||||
})
|
||||
},
|
||||
runRefresh(data) {
|
||||
this.responseData = data;
|
||||
this.loading = false;
|
||||
},
|
||||
saveAs() {
|
||||
this.$emit('saveAs', this.api);
|
||||
},
|
||||
loadCase() {
|
||||
this.refreshSign = getUUID();
|
||||
this.$refs.caseList.open();
|
||||
this.visible = true;
|
||||
},
|
||||
apiCaseClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.api.bodyUploadIds = [];
|
||||
let request = this.api.request;
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.api.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
created() {
|
||||
// 深度复制
|
||||
this.api = JSON.parse(JSON.stringify(this.apiData));
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.currentRequest = this.api.request;
|
||||
this.getResult();
|
||||
saveAsCase() {
|
||||
this.createCase = getUUID();
|
||||
this.$refs.caseList.open();
|
||||
this.loaded = false;
|
||||
},
|
||||
saveAsApi() {
|
||||
let data = {};
|
||||
let req = this.api.request;
|
||||
req.id = getUUID();
|
||||
data.request = JSON.stringify(req);
|
||||
data.method = this.api.method;
|
||||
data.status = this.api.status;
|
||||
data.userId = this.api.userId;
|
||||
data.description = this.api.description;
|
||||
this.$emit('saveAsApi', data);
|
||||
this.$emit('refresh');
|
||||
},
|
||||
updateApi() {
|
||||
let url = "/api/definition/update";
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
if(this.api.method==='ESB'){
|
||||
this.api.esbDataStruct = JSON.stringify(this.api.request.esbDataStruct);
|
||||
this.api.backEsbDataStruct = JSON.stringify(this.api.request.backEsbDataStruct);
|
||||
}
|
||||
this.$fileUpload(url, null, bodyFiles, this.api, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.syncTabs.indexOf(this.api.id) === -1) {
|
||||
this.syncTabs.push(this.api.id);
|
||||
}
|
||||
this.$emit('saveApi', this.api);
|
||||
});
|
||||
},
|
||||
selectTestCase(item) {
|
||||
if (item != null) {
|
||||
this.api.request = item.request;
|
||||
} else {
|
||||
this.api.request = this.currentRequest;
|
||||
}
|
||||
},
|
||||
getResult() {
|
||||
let url = "/api/definition/report/getReport/" + this.api.id;
|
||||
this.$get(url, response => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data.content);
|
||||
this.responseData = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 深度复制
|
||||
this.api = JSON.parse(JSON.stringify(this.apiData));
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.currentRequest = this.api.request;
|
||||
this.getResult();
|
||||
if (requireComponent != null && JSON.stringify(esbDefinition) !== '{}') {
|
||||
this.showXpackCompnent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-htt-width {
|
||||
width: 350px;
|
||||
}
|
||||
.ms-htt-width {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.environment-button {
|
||||
margin-left: 20px;
|
||||
padding: 7px;
|
||||
}
|
||||
.environment-button {
|
||||
margin-left: 20px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 3px 5px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid #783887;
|
||||
}
|
||||
.tip {
|
||||
padding: 3px 5px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid #783887;
|
||||
}
|
||||
|
||||
/deep/ .el-drawer {
|
||||
overflow: auto;
|
||||
}
|
||||
/deep/ .el-drawer {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue