feat(接口定义): #1001884 jsonschema支持多数组格式配置

【jsonschema支持多数组格式配置】https://www.tapd.cn/55049933/prong/stories/view/1155049933001001884
This commit is contained in:
song-tianyang 2021-09-06 18:01:15 +08:00 committed by 刘瑞斌
parent c31cf01219
commit 31910532d1
9 changed files with 198 additions and 135 deletions

View File

@ -130,9 +130,6 @@ public class MsHTTPSamplerProxy extends MsTestElement {
@JSONField(ordinal = 39)
private boolean customizeReq;
private MsJSR223PreProcessor preProcessor;
private MsJSR223PostProcessor postProcessor;
private void setRefElement() {
try {
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
@ -277,25 +274,27 @@ public class MsHTTPSamplerProxy extends MsTestElement {
addCertificate(config, httpSamplerTree);
//增加全局前后至脚本
if(this.preProcessor != null){
if (this.preProcessor.getEnvironmentId() == null) {
MsJSR223PreProcessor preProcessor = httpConfig.getPreProcessor();
MsJSR223PostProcessor postProcessor = httpConfig.getPostProcessor();
if(preProcessor != null){
if (preProcessor.getEnvironmentId() == null) {
if (this.getEnvironmentId() == null) {
this.preProcessor.setEnvironmentId(useEnvironment);
preProcessor.setEnvironmentId(useEnvironment);
} else {
this.preProcessor.setEnvironmentId(this.getEnvironmentId());
preProcessor.setEnvironmentId(this.getEnvironmentId());
}
}
this.preProcessor.toHashTree(httpSamplerTree, this.preProcessor.getHashTree(), config);
preProcessor.toHashTree(httpSamplerTree, preProcessor.getHashTree(), config);
}
if(this.postProcessor != null){
if (this.postProcessor.getEnvironmentId() == null) {
if(postProcessor != null){
if (postProcessor.getEnvironmentId() == null) {
if (this.getEnvironmentId() == null) {
this.postProcessor.setEnvironmentId(useEnvironment);
postProcessor.setEnvironmentId(useEnvironment);
} else {
this.postProcessor.setEnvironmentId(this.getEnvironmentId());
postProcessor.setEnvironmentId(this.getEnvironmentId());
}
}
this.postProcessor.toHashTree(httpSamplerTree, this.postProcessor.getHashTree(), config);
postProcessor.toHashTree(httpSamplerTree, postProcessor.getHashTree(), config);
}
if (CollectionUtils.isNotEmpty(hashTree)) {
for (MsTestElement el : hashTree) {
@ -343,8 +342,6 @@ public class MsHTTPSamplerProxy extends MsTestElement {
EnvironmentConfig environmentConfig = config.getConfig().get(this.getProjectId());
if (environmentConfig != null){
String useEvnId = environmentConfig.getApiEnvironmentid();
this.preProcessor = environmentConfig.getPreProcessor();
this.postProcessor = environmentConfig.getPostProcessor();
if(this.authManager == null && environmentConfig.getAuthManager() != null && environmentConfig.getAuthManager().containsKey("hashTree") ){
try {
JSONArray jsonArray = environmentConfig.getAuthManager().getJSONArray("hashTree");
@ -356,7 +353,10 @@ public class MsHTTPSamplerProxy extends MsTestElement {
if (StringUtils.isNotEmpty(useEvnId) && !StringUtils.equals(useEvnId, this.getEnvironmentId())) {
this.setEnvironmentId(useEvnId);
}
return getHttpConfig(config.getConfig().get(this.getProjectId()).getHttpConfig());
HttpConfig httpConfig = getHttpConfig(config.getConfig().get(this.getProjectId()).getHttpConfig());
httpConfig.setPreProcessor(environmentConfig.getPreProcessor());
httpConfig.setPostProcessor(environmentConfig.getPostProcessor());
return httpConfig;
}
}
return null;

View File

@ -77,9 +77,6 @@ public class MsJDBCSampler extends MsTestElement {
@JSONField(ordinal = 31)
private boolean customizeReq;
private MsJSR223PreProcessor preProcessor;
private MsJSR223PostProcessor postProcessor;
@Override
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, MsParameter msParameter) {
ParameterConfig config = (ParameterConfig) msParameter;
@ -116,19 +113,18 @@ public class MsJDBCSampler extends MsTestElement {
}
}
}
EnvironmentConfig envConfig = null;
// 自选了数据源
if (config.isEffective(this.getProjectId()) && CollectionUtils.isNotEmpty(config.getConfig().get(this.getProjectId()).getDatabaseConfigs())
&& isDataSource(config.getConfig().get(this.getProjectId()).getDatabaseConfigs())) {
this.dataSource = null;
this.initDataSource();
envConfig = this.initDataSource();
} else {
this.dataSource = null;
// 取当前环境下默认的一个数据源
if (config.isEffective(this.getProjectId())) {
if(config.getConfig().get(this.getProjectId()) != null){
EnvironmentConfig envConfig = config.getConfig().get(this.getProjectId());
this.preProcessor = envConfig.getPreProcessor();
this.postProcessor = envConfig.getPostProcessor();
envConfig = config.getConfig().get(this.getProjectId());
if(CollectionUtils.isNotEmpty(envConfig.getDatabaseConfigs())){
this.dataSource = envConfig.getDatabaseConfigs().get(0);
}
@ -140,7 +136,7 @@ public class MsJDBCSampler extends MsTestElement {
// 用自身的数据
if (StringUtils.isNotEmpty(dataSourceId)) {
this.dataSource = null;
this.initDataSource();
envConfig = this.initDataSource();
}
if (this.dataSource == null) {
MSException.throwException("数据源为空无法执行");
@ -153,26 +149,33 @@ public class MsJDBCSampler extends MsTestElement {
tree.add(arguments);
}
MsJSR223PreProcessor preProcessor = null;
MsJSR223PostProcessor postProcessor = null;
if(envConfig != null){
preProcessor = envConfig.getPreProcessor();
postProcessor = envConfig.getPostProcessor();
}
//增加全局前后至脚本
if(this.preProcessor != null){
if (this.preProcessor.getEnvironmentId() == null) {
if(preProcessor != null){
if (preProcessor.getEnvironmentId() == null) {
if (this.getEnvironmentId() == null) {
this.preProcessor.setEnvironmentId(useEnvironment);
preProcessor.setEnvironmentId(useEnvironment);
} else {
this.preProcessor.setEnvironmentId(this.getEnvironmentId());
preProcessor.setEnvironmentId(this.getEnvironmentId());
}
}
this.preProcessor.toHashTree(samplerHashTree, this.preProcessor.getHashTree(), config);
preProcessor.toHashTree(samplerHashTree, preProcessor.getHashTree(), config);
}
if(this.postProcessor != null){
if (this.postProcessor.getEnvironmentId() == null) {
if(postProcessor != null){
if (postProcessor.getEnvironmentId() == null) {
if (this.getEnvironmentId() == null) {
this.postProcessor.setEnvironmentId(useEnvironment);
postProcessor.setEnvironmentId(useEnvironment);
} else {
this.postProcessor.setEnvironmentId(this.getEnvironmentId());
postProcessor.setEnvironmentId(this.getEnvironmentId());
}
}
this.postProcessor.toHashTree(samplerHashTree, this.postProcessor.getHashTree(), config);
postProcessor.toHashTree(samplerHashTree, postProcessor.getHashTree(), config);
}
if (CollectionUtils.isNotEmpty(hashTree)) {
@ -243,11 +246,12 @@ public class MsJDBCSampler extends MsTestElement {
}
}
private void initDataSource() {
private EnvironmentConfig initDataSource() {
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentId);
EnvironmentConfig envConfig = null;
if (environment != null && environment.getConfig() != null) {
EnvironmentConfig envConfig = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
envConfig = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
if (CollectionUtils.isNotEmpty(envConfig.getDatabaseConfigs())) {
envConfig.getDatabaseConfigs().forEach(item -> {
if (item.getId().equals(this.dataSourceId)) {
@ -256,11 +260,8 @@ public class MsJDBCSampler extends MsTestElement {
}
});
}
if(envConfig != null){
this.preProcessor = envConfig.getPreProcessor();
this.postProcessor = envConfig.getPostProcessor();
}
}
return envConfig;
}
private Arguments arguments(String name, List<KeyValue> variables) {

View File

@ -107,9 +107,6 @@ public class MsTCPSampler extends MsTestElement {
@JSONField(ordinal = 45)
private boolean customizeReq;
private MsJSR223PreProcessor preProcessor;
private MsJSR223PostProcessor postProcessor;
/**
* 新加两个参数场景保存/修改时需要的参数不会传递JMeter只是用于最后的保留
*/
@ -131,8 +128,10 @@ public class MsTCPSampler extends MsTestElement {
this.setProjectId(config.getProjectId());
config.setConfig(ElementUtil.getEnvironmentConfig(useEnvironment, this.getProjectId(), this.isMockEnvironment()));
}
EnvironmentConfig envConfig = null;
if (config.getConfig() != null) {
parseEnvironment(config.getConfig().get(this.projectId));
envConfig = config.getConfig().get(this.projectId);
parseEnvironment(envConfig);
}
// 添加环境中的公共变量
@ -149,26 +148,32 @@ public class MsTCPSampler extends MsTestElement {
samplerHashTree.add(tcpPreProcessor.getJSR223PreProcessor());
}
MsJSR223PreProcessor preProcessor = null;
MsJSR223PostProcessor postProcessor = null;
if(envConfig != null){
preProcessor = envConfig.getPreProcessor();
postProcessor = envConfig.getPostProcessor();
}
//增加全局前后至脚本
if(this.preProcessor != null){
if (this.preProcessor.getEnvironmentId() == null) {
if(preProcessor != null){
if (preProcessor.getEnvironmentId() == null) {
if (this.getEnvironmentId() == null) {
this.preProcessor.setEnvironmentId(useEnvironment);
preProcessor.setEnvironmentId(useEnvironment);
} else {
this.preProcessor.setEnvironmentId(this.getEnvironmentId());
preProcessor.setEnvironmentId(this.getEnvironmentId());
}
}
this.preProcessor.toHashTree(samplerHashTree, this.preProcessor.getHashTree(), config);
preProcessor.toHashTree(samplerHashTree, preProcessor.getHashTree(), config);
}
if(this.postProcessor != null){
if (this.postProcessor.getEnvironmentId() == null) {
if(postProcessor != null){
if (postProcessor.getEnvironmentId() == null) {
if (this.getEnvironmentId() == null) {
this.postProcessor.setEnvironmentId(useEnvironment);
postProcessor.setEnvironmentId(useEnvironment);
} else {
this.postProcessor.setEnvironmentId(this.getEnvironmentId());
postProcessor.setEnvironmentId(this.getEnvironmentId());
}
}
this.postProcessor.toHashTree(samplerHashTree, this.postProcessor.getHashTree(), config);
postProcessor.toHashTree(samplerHashTree, postProcessor.getHashTree(), config);
}
if (CollectionUtils.isNotEmpty(hashTree)) {
hashTree.forEach(el -> {
@ -217,10 +222,6 @@ public class MsTCPSampler extends MsTestElement {
}
private void parseEnvironment(EnvironmentConfig config) {
if(config != null){
this.preProcessor = config.getPreProcessor();
this.postProcessor = config.getPostProcessor();
}
if (!isCustomizeReq() && config != null) {
if (!isCustomizeReq() && config != null) {
this.server = config.getTcpConfig().getServer();

View File

@ -1,5 +1,7 @@
package io.metersphere.api.dto.scenario;
import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor;
import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
import io.metersphere.commons.utils.BeanUtils;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
@ -19,6 +21,9 @@ public class HttpConfig {
private List<HttpConfigCondition> conditions;
private List<KeyValue> headers;
private MsJSR223PreProcessor preProcessor;
private MsJSR223PostProcessor postProcessor;
public HttpConfig initHttpConfig(HttpConfigCondition configCondition) {
HttpConfig config = new HttpConfig();
config.isMock = this.isMock;

View File

@ -211,13 +211,17 @@ public class JSONSchemaGenerator {
// 先设置空值
List<Object> array = new LinkedList<>();
JsonObject itemsObject = null;
JsonArray jsonArray = new JsonArray();
if (object.has("items") && object.get("items").isJsonArray()) {
itemsObject = object.get("items").getAsJsonArray().get(0).getAsJsonObject();
jsonArray = object.get("items").getAsJsonArray();
} else {
itemsObject = object.get("items").getAsJsonObject();
JsonObject itemsObject = itemsObject = object.get("items").getAsJsonObject();
array.add(itemsObject);
}
for(int i = 0; i < jsonArray.size(); i ++){
JsonObject itemsObject = jsonArray.get(i).getAsJsonObject();
if (object.has("items")) {
if (itemsObject.has("enum")) {
array.add(analyzeEnumProperty(itemsObject));
@ -257,11 +261,16 @@ public class JSONSchemaGenerator {
} else if (itemsObject.has("$ref")) {
analyzeRef(concept, propertyName, itemsObject);
}else if(itemsObject.has("type") && itemsObject.get("type") instanceof JsonPrimitive){
JSONObject newJsonObj = new JSONObject();
analyzeProperty(newJsonObj,propertyName+"_item",itemsObject);
array.add(newJsonObj.get(propertyName+"_item"));
}
} else if (object.has("items") && object.get("items").isJsonArray()) {
JsonArray itemsObjectArray = object.get("items").getAsJsonArray();
array.add(itemsObjectArray);
}
}
concept.put(propertyName, array);

View File

@ -217,6 +217,7 @@
this.response.body = body;
}
this.request.clazzName = TYPE_TO_C.get(this.request.type);
this.sort(this.request.hashTree);
},
saveApi(data) {

View File

@ -128,7 +128,7 @@
import Jsr233ProcessorContent from "../../../../automation/scenario/common/Jsr233ProcessorContent";
import JSR223PreProcessor from "../../jmeter/components/pre-processors/jsr223-pre-processor";
import ApiDefinitionStepButton from "../components/ApiDefinitionStepButton";
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
export default {
name: "TcpBasisParameters",
@ -191,6 +191,9 @@
if (!this.request.tcpPreProcessor) {
this.$set(this.request, 'tcpPreProcessor', new JSR223PreProcessor())
}
if(this.request.tcpPreProcessor){
this.request.tcpPreProcessor.clazzName = TYPE_TO_C.get(this.request.tcpPreProcessor.type);
}
if(!this.request.connectEncoding){
this.request.connectEncoding = "UTF-8";
}

View File

@ -155,7 +155,7 @@
import JSR223PreProcessor from "../../jmeter/components/pre-processors/jsr223-pre-processor";
import ApiDefinitionStepButton from "../components/ApiDefinitionStepButton";
import TcpXmlTable from "@/business/components/api/definition/components/complete/table/TcpXmlTable";
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
export default {
name: "MsTcpFormatParameters",
@ -232,6 +232,9 @@
if (!this.request.tcpPreProcessor) {
this.$set(this.request, 'tcpPreProcessor', new JSR223PreProcessor())
}
if(this.request.tcpPreProcessor){
this.request.tcpPreProcessor.clazzName = TYPE_TO_C.get(this.request.tcpPreProcessor.type);
}
if(!this.request.connectEncoding){
this.request.connectEncoding = "UTF-8";
}

View File

@ -21,7 +21,7 @@
</el-select>
</el-col>
<el-col :span="4">
<ms-mock :disabled="pickValue.type==='object'" :schema="pickValue"/>
<ms-mock :disabled="pickValue.type==='object' || pickValue.type==='array'" :schema="pickValue"/>
</el-col>
<el-col :span="4">
<el-input v-model="pickValue.description" class="ms-col-title" :placeholder="$t('schema.description')" size="small"/>
@ -30,7 +30,7 @@
<el-tooltip class="item" effect="dark" :content="$t('schema.adv_setting')" placement="top">
<i class="el-icon-setting" @click="onSetting"/>
</el-tooltip>
<el-tooltip v-if="isObject" :content="$t('schema.add_child_node')" placement="top">
<el-tooltip v-if="isObject || isArray" :content="$t('schema.add_child_node')" placement="top">
<i class="el-icon-plus" @click="addChild" style="margin-left: 10px"/>
</el-tooltip>
<el-tooltip v-if="!root && !isItem" :content="$t('schema.remove_node')" placement="top">
@ -40,10 +40,11 @@
</el-row>
<template v-if="!hidden&&pickValue.properties && !isArray">
<json-schema-editor v-for="(item,key,index) in pickValue.properties" :value="{[key]:item}" :parent="pickValue" :key="index" :deep="deep+1" :root="false" class="children" :lang="lang" :custom="custom"/>
<json-schema-editor v-for="(item,key,index) in pickValue.properties" :value="{[key]:item}" :parent="pickValue" :key="index" :deep="deep+1" :root="false" class="children" :lang="lang" :custom="custom" @changeAllItemsType="changeAllItemsType"/>
</template>
<template v-if="isArray">
<json-schema-editor :value="{items:pickValue.items}" :deep="deep+1" disabled isItem :root="false" class="children" :lang="lang" :custom="custom"/>
<!-- <json-schema-editor :value="{items:pickValue.items}" :deep="deep+1" disabled isItem :root="false" class="children" :lang="lang" :custom="custom"/>-->
<json-schema-editor v-for="(item,key,index) in pickValue.items" :value="{[key]:item}" :parent="pickValue" :key="index" :deep="deep+1" :root="false" class="children" :lang="lang" :custom="custom" @changeAllItemsType="changeAllItemsType"/>
</template>
<!-- 高级设置-->
<el-dialog append-to-body :close-on-click-modal="false" :title="$t('schema.adv_setting')" :visible.sync="modalVisible" :destroy-on-close="true"
@ -216,12 +217,30 @@
this.$set(this.parent, 'properties', p)
},
onChangeType() {
if(this.parent && this.parent.type === 'array'){
this.$emit('changeAllItemsType',this.pickValue.type);
}else{
this.$delete(this.pickValue, 'properties')
this.$delete(this.pickValue, 'items')
this.$delete(this.pickValue, 'required')
this.$delete(this.pickValue, 'mock')
if (this.isArray) {
this.$set(this.pickValue, 'items', {type: 'string', mock: {mock: ""}})
this.$set(this.pickValue, 'items', [{type: 'string', mock: {mock: ""}}]);
}
}
},
changeAllItemsType(changeType){
if(this.isArray && this.pickValue.items && this.pickValue.items.length > 0){
this.pickValue.items.forEach(item => {
item.type = changeType;
this.$delete(item, 'properties')
this.$delete(item, 'items')
this.$delete(item, 'required')
this.$delete(item, 'mock')
if (changeType === 'array') {
this.$set(item, 'items', [{type: 'string', mock: {mock: ""}}]);
}
});
}
},
onCheck(e) {
@ -254,12 +273,23 @@
required.length === 0 && this.$delete(parent, 'required')
},
addChild() {
const node = this.pickValue;
if (this.isArray) {
let childObj = {type: 'string', mock: {mock: ""}}
if(node.items && node.items.length > 0){
childObj.type = node.items[0].type;
node.items.push(childObj);
}else {
this.$set(this.pickValue, 'items', [childObj]);
}
}else {
const name = this._joinName()
const type = 'string'
const node = this.pickValue
node.properties || this.$set(node, 'properties', {})
const props = node.properties
this.$set(props, name, {type: type, mock: {mock: ""}})
}
},
addCustomNode() {
this.$set(this.addProp, 'key', this._joinName())
@ -272,6 +302,7 @@
this.customing = false
},
removeNode() {
if(this.parent.type && this.parent.type === 'object'){
const {properties, required} = this.parent
this.$delete(properties, this.pickKey)
if (required) {
@ -279,6 +310,15 @@
pos >= 0 && required.splice(pos, 1)
required.length === 0 && this.$delete(this.parent, 'required')
}
}else if(this.parent.type && this.parent.type === 'array'){
const {items, required} = this.parent
this.$delete(items, this.pickKey)
if (required) {
const pos = required.indexOf(this.pickKey)
pos >= 0 && required.splice(pos, 1)
required.length === 0 && this.$delete(this.parent, 'required')
}
}
},
_joinName() {
return `feild_${this.deep}_${this.countAdd++}_${getUUID().substring(0, 5)}`