feat: TCP请求的相关交互和展示优化

接口定义TCP请求的交互和展示优化,TCP设置增加编码设置,TCP表头的请求类型改为协议方法,ESB报文增加Mock参数
This commit is contained in:
song-tianyang 2021-06-04 10:41:22 +08:00 committed by 刘瑞斌
parent 3d0edb2e35
commit 214a6385fe
12 changed files with 119 additions and 27 deletions

View File

@ -20,6 +20,7 @@ import io.metersphere.commons.constants.DelimiterConstants;
import io.metersphere.commons.constants.MsTestElementConstants;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ScriptEngineUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.collections.CollectionUtils;
@ -35,10 +36,13 @@ import org.apache.jmeter.testelement.property.StringProperty;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Data
@EqualsAndHashCode(callSuper = true)
@ -82,6 +86,9 @@ public class MsTCPSampler extends MsTestElement {
private String protocol = "TCP";
@JSONField(ordinal = 39)
private String projectId;
@JSONField(ordinal = 40)
private String connectEncoding;
/**
* 新加两个参数场景保存/修改时需要的参数不会传递JMeter只是用于最后的保留
@ -195,7 +202,21 @@ public class MsTCPSampler extends MsTestElement {
tcpSampler.setCloseConnection(String.valueOf(this.isCloseConnection()));
tcpSampler.setSoLinger(this.getSoLinger());
tcpSampler.setEolByte(this.getEolByte());
tcpSampler.setRequestData(this.getRequest());
String value = this.getRequest();
if(StringUtils.isNotEmpty(this.getConnectEncoding())){
if(StringUtils.equalsIgnoreCase("utf-8",this.getConnectEncoding())){
value = new String(value.getBytes(),StandardCharsets.UTF_8);
}else if(StringUtils.equalsIgnoreCase("gbk",this.getConnectEncoding())){
try {
value = new String(value.getBytes(),"GBK");
}catch (Exception e){
}
}
}
tcpSampler.setRequestData(value);
tcpSampler.setProperty(ConfigTestElement.USERNAME, this.getUsername());
tcpSampler.setProperty(ConfigTestElement.PASSWORD, this.getPassword());
return tcpSampler;
@ -213,7 +234,19 @@ public class MsTCPSampler extends MsTestElement {
if (CollectionUtils.isNotEmpty(this.parameters)) {
this.parameters.forEach(item -> {
names.add(new StringProperty(new Integer(new Random().nextInt(1000000)).toString(), item.getName()));
threadValues.add(new StringProperty(new Integer(new Random().nextInt(1000000)).toString(), item.getValue()));
String value = item.getValue();
value = this.formatMockValue(value);
if(StringUtils.isNotEmpty(this.getConnectEncoding())){
if(StringUtils.equalsIgnoreCase("utf-8",this.getConnectEncoding())){
value = new String(value.getBytes(),StandardCharsets.UTF_8);
}else if(StringUtils.equalsIgnoreCase("gbk",this.getConnectEncoding())){
try {
value = new String(value.getBytes(),"GBK");
}catch (Exception e){
}
}
}
threadValues.add(new StringProperty(new Integer(new Random().nextInt(1000000)).toString(), value));
});
}
userParameters.setNames(new CollectionProperty(UserParameters.NAMES, names));
@ -222,7 +255,29 @@ public class MsTCPSampler extends MsTestElement {
userParameters.setThreadLists(new CollectionProperty(UserParameters.THREAD_VALUES, collectionPropertyList));
tree.add(userParameters);
}
private String formatMockValue(String value) {
String patten = ">@[^>@]+</?";
Pattern r = Pattern.compile(patten);
try{
Matcher m = r.matcher(value);
while (m.find()){
String findStr = m.group();
if(findStr.length() > 3){
findStr = findStr.substring(1,findStr.length()-2);
String replaceStr = ScriptEngineUtils.calculate(findStr);
if(StringUtils.equals(findStr,replaceStr)){
replaceStr = "";
}
value = value.replace(">"+findStr+"</",">"+replaceStr+"</");
m = r.matcher(value);
}
}
}catch (Exception e){
}
return value;
}
private ConfigTestElement tcpConfig() {
ConfigTestElement configTestElement = new ConfigTestElement();
configTestElement.setEnabled(true);

View File

@ -39,11 +39,9 @@ public class EsbApiParamService {
public EsbApiParamsWithBLOBs createEsbApiParam(String resourceId, String esbDataStruct, String backedEsbDataStrcut, String backedScript) {
EsbApiParamsWithBLOBs model = null;
EsbApiParamsExample example = new EsbApiParamsExample();
example.createCriteria().andResourceIdEqualTo(resourceId);
List<EsbApiParamsWithBLOBs> list = esbApiParamsMapper.selectByExampleWithBLOBs(example);
if (list.isEmpty()) {
String uuid = UUID.randomUUID().toString();
model = new EsbApiParamsWithBLOBs();

View File

@ -41,7 +41,7 @@
sortable="custom"
column-key="method"
:filters="methodFilters"
:label="$t('api_test.definition.api_type')"
:label="getApiRequestTypeName"
width="120px">
<template v-slot:default="scope">
<el-tag size="mini"
@ -228,6 +228,13 @@
} else {
return new Set();
}
},
getApiRequestTypeName(){
if(this.currentProtocol === 'TCP'){
return this.$t('api_test.definition.api_agreement');
}else{
return this.$t('api_test.definition.api_type');
}
}
},
methods: {

View File

@ -69,7 +69,12 @@ export default {
return {
validated: false,
apiProtocol: "TCP",
methodTypes:["TCP"],
methodTypes:[
{
'key':"TCP",
'value':this.$t('api_test.request.tcp.general_format'),
}
],
showXpackCompnent:false,
}
},
@ -85,7 +90,10 @@ export default {
this.showXpackCompnent = true;
if(hasLicense()){
if(this.methodTypes.length == 1){
this.methodTypes.push("ESB");
let esbMethodType = {};
esbMethodType.key = "ESB";
esbMethodType.value="ESB";
this.methodTypes.push(esbMethodType);
}
}

View File

@ -8,7 +8,7 @@
<!-- <el-input class="ms-http-input" size="small" v-model="basicForm.name"/>-->
<el-input v-model="basicForm.name" class="ms-http-input" size="small">
<el-select v-model="basicForm.method" slot="prepend" style="width: 100px" size="small" @change="methodChange">
<el-option v-for="item in methodTypes" :key="item" :label="item" :value="item"/>
<el-option v-for="item in methodTypes" :key="item.key" :label="item.value" :value="item.key"/>
</el-select>
</el-input>
@ -16,20 +16,6 @@
</el-col>
<el-col :span="12">
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
<!--<el-select class="ms-http-input" size="small" v-model="basicForm.moduleId" style="width: 100%" @change="reload">-->
<!--<div v-if="moduleOptions.length>0">-->
<!--<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>-->
<!--</div>-->
<!--<div v-else>-->
<!--<el-option :key="0" :value="''">-->
<!--<div style="margin-left: 40px">-->
<!--<span style="font-size: 14px;color: #606266;font-weight: 48.93">{{ $t('api_test.definition.select_comp.no_data') }},-->
<!--</span>-->
<!--<el-link type="primary" @click="createModules">{{ $t('api_test.definition.select_comp.add_data') }}</el-link>-->
<!--</div>-->
<!--</el-option>-->
<!--</div>-->
<!--</el-select>-->
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="basicForm.moduleId" @getValue="setModule" :obj="moduleObj" clearable checkStrictly/>
</el-form-item>

View File

@ -70,7 +70,7 @@
:filters="methodFilters"
:fields-width="fieldsWidth"
min-width="120px"
:label="$t('api_test.definition.api_type')">
:label="getApiRequestTypeName">
<template v-slot:default="scope" class="request-method">
<el-tag size="mini"
:style="{'background-color': getColor(true, scope.row.method), border: getColor(true, scope.row.method)}"
@ -398,6 +398,13 @@ export default {
selectRows() {
return this.$refs.apiDefinitionTable.getSelectRows();
},
getApiRequestTypeName(){
if(this.currentProtocol === 'TCP'){
return this.$t('api_test.definition.api_agreement');
}else{
return this.$t('api_test.definition.api_type');
}
}
},
created: function () {
if (this.trashEnable) {
@ -444,6 +451,12 @@ export default {
if (this.$refs.apiDefinitionTable) {
this.$refs.apiDefinitionTable.clearSelectRows();
}
//
if(this.$refs.caseList){
this.$refs.caseList.handleClose();
}
initCondition(this.condition, this.condition.selectAll);
this.selectDataCounts = 0;
this.condition.moduleIds = this.selectNodeIds;

View File

@ -17,7 +17,6 @@
<el-row>
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{$t("commons.batch_add")}}</el-link>
</el-row>
<ms-api-key-value :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :suggestions="headerSuggestions" :items="headers" :need-mock="true"/>
</el-tab-pane>

View File

@ -73,12 +73,12 @@
</el-col>
</el-row>
<el-row :gutter="10" style="margin-left: 30px">
<el-col :span="9">
<el-col :span="6">
<el-form-item :label="$t('api_test.request.tcp.re_use_connection')">
<el-checkbox v-model="request.reUseConnection"/>
</el-form-item>
</el-col>
<el-col :span="9">
<el-col :span="6">
<el-form-item :label="$t('api_test.request.tcp.close_connection')">
<el-checkbox v-model="request.closeConnection"/>
</el-form-item>
@ -88,6 +88,13 @@
<el-checkbox v-model="request.nodelay"/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="Connect encoding">
<el-select v-model="request.connectEncoding" style="width: 100px" size="small">
<el-option v-for="item in connectEncodingArr" :key="item.key" :label="item.value" :value="item.key"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
@ -158,6 +165,16 @@
isReloadData: false,
options: API_STATUS,
currentProjectId: "",
connectEncodingArr:[
{
'key':'UTF-8',
'value':'UTF-8',
},
{
'key':'GBK',
'value':'GBK',
},
],
rules: {
classname: [{required: true, message: "请选择TCPClient", trigger: 'change'}],
server: [{required: true, message: this.$t('api_test.request.tcp.server_cannot_be_empty'), trigger: 'blur'}],
@ -174,6 +191,9 @@
if (!this.request.tcpPreProcessor) {
this.$set(this.request, 'tcpPreProcessor', new JSR223PreProcessor())
}
if(!this.request.connectEncoding){
this.request.connectEncoding = "UTF-8";
}
this.getEnvironments();
},
methods: {

@ -1 +1 @@
Subproject commit 1ac463ed7ef667d3f75c3ba64fab8331ecaa02c2
Subproject commit 34379f3a7e7d52b4a9c0194325b3ea02db5cc8eb

View File

@ -682,6 +682,7 @@ export default {
api_name: "Api name",
api_status: "Api status",
api_type: "Api type",
api_agreement: "Method",
api_path: "Api path",
api_principal: "Api principal",
api_last_time: "Last update time",
@ -1050,6 +1051,7 @@ export default {
variable_names: "Variable names",
},
tcp: {
general_format: "General",
server: "Server Name or IP",
port: "Port Number",
connect: "Connect(ms)",

View File

@ -682,6 +682,7 @@ export default {
api_name: "接口名称",
api_status: "接口状态",
api_type: "请求类型",
api_agreement: "协议/方法",
api_path: "路径",
api_principal: "负责人",
api_last_time: "最后更新时间",
@ -1052,6 +1053,7 @@ export default {
variable_names: "按列存储",
},
tcp: {
general_format: "通用格式",
server: "服务器名或IP",
port: "端口",
connect: "连接(ms)",

View File

@ -682,6 +682,7 @@ export default {
api_name: "接口名稱",
api_status: "接口狀態",
api_type: "請求類型",
api_agreement: "協議/方法",
api_path: "路徑",
api_principal: "負責人",
api_last_time: "最後更新時間",
@ -1052,6 +1053,7 @@ export default {
variable_names: "按列存儲",
},
tcp: {
general_format: "通用格式",
server: "服務器名或IP",
port: "端口",
connect: "連接(ms)",