refactor(接口测试): 完善请求详情java doc

This commit is contained in:
AgAngle 2024-01-28 11:55:31 +08:00 committed by Craftsman
parent 21a711e954
commit ae6fb6184a
48 changed files with 664 additions and 101 deletions

View File

@ -1,16 +1,25 @@
package io.metersphere.api.dto; package io.metersphere.api.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/**
* 接口执行所需要的文件
*/
@Data @Data
public class ApiFile { public class ApiFile {
/** /**
* 记录文件的ID防止重名 * 记录文件的ID防止重名
* 生成脚本时通过 fileId + value(文件名) 获取文件路径 * 生成脚本时通过 fileId + fileName(文件名) 获取文件路径
*/ */
@NotBlank
@Size(max = 50)
private String fileId; private String fileId;
/** /**
* 文件名 * 文件名
*/ */
@NotBlank
@Size(max = 200)
private String fileName; private String fileName;
} }

View File

@ -3,12 +3,15 @@ package io.metersphere.api.dto.request;
import io.metersphere.api.dto.request.assertion.MsAssertionConfig; import io.metersphere.api.dto.request.assertion.MsAssertionConfig;
import io.metersphere.api.dto.request.processors.MsProcessorConfig; import io.metersphere.api.dto.request.processors.MsProcessorConfig;
import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
/** /**
* 协议插件中通用的配置 * 协议插件中通用的配置
* <pre>
* 添加到对应元素的 children 属性中 * 添加到对应元素的 children 属性中
* </pre>
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-12-25 10:50 * @CreateTime: 2023-12-25 10:50
*/ */
@ -18,13 +21,16 @@ public class MsCommonElement extends AbstractMsTestElement {
/** /**
* 前置处理器配置 * 前置处理器配置
*/ */
@Valid
private MsProcessorConfig preProcessorConfig; private MsProcessorConfig preProcessorConfig;
/** /**
* 后置处理器配置 * 后置处理器配置
*/ */
@Valid
private MsProcessorConfig postProcessorConfig; private MsProcessorConfig postProcessorConfig;
/** /**
* 断言配置 * 断言配置
*/ */
@Valid
private MsAssertionConfig assertionConfig; private MsAssertionConfig assertionConfig;
} }

View File

@ -2,10 +2,24 @@ package io.metersphere.api.dto.request.assertion;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.metersphere.api.dto.request.processors.extract.JSONPathExtract;
import io.metersphere.api.dto.request.processors.extract.RegexExtract;
import io.metersphere.api.dto.request.processors.extract.XPathExtract;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/** /**
* 断言 * 断言
* <pre>
* 该参数传参时需要传入 assertionType 字段用于区分是哪种断言
* assertionType 取值为:
* RESPONSE_CODE {@link MsResponseCodeAssertion}
* RESPONSE_HEADER {@link MsResponseHeaderAssertion}
* RESPONSE_BODY {@link MsResponseBodyAssertion}
* RESPONSE_TIME {@link MsResponseTimeAssertion}
* SCRIPT {@link MsScriptAssertion}
* VARIABLE {@link MsVariableAssertion}
* </pre>
*/ */
@Data @Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "assertionType") @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "assertionType")
@ -20,10 +34,12 @@ import lombok.Data;
public abstract class MsAssertion { public abstract class MsAssertion {
/** /**
* 是否启用 * 是否启用
* 默认启用
*/ */
private Boolean enable = true; private Boolean enable = true;
/** /**
* 断言名称 * 断言名称
*/ */
@Size(max = 100)
private String name; private String name;
} }

View File

@ -13,8 +13,9 @@ import java.util.List;
public class MsAssertionConfig { public class MsAssertionConfig {
/** /**
* 是否启用全局断言 * 是否启用全局断言
* 默认为 false
*/ */
private Boolean enableGlobal; private Boolean enableGlobal = false;
/** /**
* 断言列表 * 断言列表
*/ */

View File

@ -5,6 +5,8 @@ import io.metersphere.api.dto.request.assertion.body.MsDocumentAssertion;
import io.metersphere.api.dto.request.assertion.body.MsJSONPathAssertion; import io.metersphere.api.dto.request.assertion.body.MsJSONPathAssertion;
import io.metersphere.api.dto.request.assertion.body.MsRegexAssertion; import io.metersphere.api.dto.request.assertion.body.MsRegexAssertion;
import io.metersphere.api.dto.request.assertion.body.MsXPathAssertion; import io.metersphere.api.dto.request.assertion.body.MsXPathAssertion;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
import java.util.HashMap; import java.util.HashMap;
@ -26,24 +28,29 @@ public class MsResponseBodyAssertion extends MsAssertion {
* 后端从设计层面支持多种断言前端只支持一种 * 后端从设计层面支持多种断言前端只支持一种
* 同时切换可以同时持久化两种类型 * 同时切换可以同时持久化两种类型
* *
* @see MsBodyAssertionType * 取值参考 {@link MsBodyAssertionType}
*/ */
@EnumValue(enumClass = MsBodyAssertionType.class)
private String assertionBodyType; private String assertionBodyType;
/** /**
* jsonPath断言 * jsonPath断言
*/ */
@Valid
private MsJSONPathAssertion jsonPathAssertion; private MsJSONPathAssertion jsonPathAssertion;
/** /**
* xpath断言 * xpath断言
*/ */
@Valid
private MsXPathAssertion xpathAssertion; private MsXPathAssertion xpathAssertion;
/** /**
* 文档断言 * 文档断言
*/ */
@Valid
private MsDocumentAssertion documentAssertion; private MsDocumentAssertion documentAssertion;
/** /**
* 正则断言 * 正则断言
*/ */
@Valid
private MsRegexAssertion regexAssertion; private MsRegexAssertion regexAssertion;
private static Map<MsBodyAssertionType, Class> bodyAssertionClassMap = new HashMap<>(); private static Map<MsBodyAssertionType, Class> bodyAssertionClassMap = new HashMap<>();
@ -68,6 +75,9 @@ public class MsResponseBodyAssertion extends MsAssertion {
return boadyAssertionMap.get(MsBodyAssertionType.valueOf(assertionBodyType)); return boadyAssertionMap.get(MsBodyAssertionType.valueOf(assertionBodyType));
} }
/**
* 请求体断言类型
*/
public enum MsBodyAssertionType { public enum MsBodyAssertionType {
/** /**
* 正则断言 * 正则断言

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.request.assertion; package io.metersphere.api.dto.request.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/** /**
@ -15,8 +16,9 @@ public class MsResponseCodeAssertion extends MsAssertion {
* 不校验即忽略状态 * 不校验即忽略状态
* 选择其他条件时也忽略状态 * 选择其他条件时也忽略状态
* 不校验可搭配其他校验使用 * 不校验可搭配其他校验使用
* @see io.metersphere.sdk.constants.MsAssertionCondition * 取值参考 {@link io.metersphere.sdk.constants.MsAssertionCondition}
*/ */
@Size(max = 50)
private String condition; private String condition;
/** /**
* 匹配值 * 匹配值

View File

@ -1,6 +1,8 @@
package io.metersphere.api.dto.request.assertion; package io.metersphere.api.dto.request.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -13,14 +15,21 @@ import java.util.List;
@Data @Data
@JsonTypeName("RESPONSE_HEADER") @JsonTypeName("RESPONSE_HEADER")
public class MsResponseHeaderAssertion extends MsAssertion { public class MsResponseHeaderAssertion extends MsAssertion {
/**
* 断言列表
*/
@Valid
private List<ResponseHeaderAssertionItem> assertions; private List<ResponseHeaderAssertionItem> assertions;
/**
* 响应头断言项
*/
@Data @Data
public static class ResponseHeaderAssertionItem { public static class ResponseHeaderAssertionItem {
/** /**
* 是否启用 * 是否启用
* 默认启用
*/ */
private Boolean enable = true; private Boolean enable = true;
/** /**
@ -29,8 +38,9 @@ public class MsResponseHeaderAssertion extends MsAssertion {
private String header; private String header;
/** /**
* 匹配条件 * 匹配条件
* 值为 MsAssertionCondition * 取值参考 {@link io.metersphere.sdk.constants.MsAssertionCondition}
*/ */
@EnumValue(enumClass = io.metersphere.sdk.constants.MsAssertionCondition.class)
private String condition; private String condition;
/** /**
* 匹配值 * 匹配值

View File

@ -9,5 +9,9 @@ import lombok.Data;
*/ */
@Data @Data
public abstract class MsBodyAssertionItem { public abstract class MsBodyAssertionItem {
/**
* 是否启用
* 默认启用
*/
private Boolean enable = true; private Boolean enable = true;
} }

View File

@ -1,5 +1,8 @@
package io.metersphere.api.dto.request.assertion.body; package io.metersphere.api.dto.request.assertion.body;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/** /**
@ -13,6 +16,7 @@ public class MsDocumentAssertion extends MsBodyAssertionItem {
* 跟随定义的apiId * 跟随定义的apiId
* 传空为不跟随接口定义 * 传空为不跟随接口定义
*/ */
@Size(max = 50)
private String followApiId; private String followApiId;
/** /**
* 文档类型 * 文档类型
@ -21,16 +25,20 @@ public class MsDocumentAssertion extends MsBodyAssertionItem {
* 这里跟前端数据结构有差异 * 这里跟前端数据结构有差异
* 后端从设计层面支持多种文档格式前端只支持一种 * 后端从设计层面支持多种文档格式前端只支持一种
* 同时切换可以同时持久化两种格式 * 同时切换可以同时持久化两种格式
* @see DocumentType *
*/ * 取值参考 {@link DocumentType}
= */
@EnumValue(enumClass = DocumentType.class)
private String documentType; private String documentType;
/** /**
* json格式的文档断言 * json格式的文档断言
*/ */
@Valid
private MsDocumentAssertionElement jsonAssertion; private MsDocumentAssertionElement jsonAssertion;
/** /**
* xml格式的文档断言 * xml格式的文档断言
*/ */
@Valid
private MsDocumentAssertionElement xmlAssertion; private MsDocumentAssertionElement xmlAssertion;
public enum DocumentType { public enum DocumentType {

View File

@ -1,10 +1,16 @@
package io.metersphere.api.dto.request.assertion.body; package io.metersphere.api.dto.request.assertion.body;
import io.metersphere.sdk.constants.MsAssertionCondition;
import io.metersphere.sdk.constants.ValueEnum;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
/** /**
* 文档断言项
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-23 11:43 * @CreateTime: 2023-11-23 11:43
*/ */
@ -14,6 +20,7 @@ public class MsDocumentAssertionElement {
/** /**
* 参数名 * 参数名
*/ */
@Size(max = 100)
private String paramName; private String paramName;
/** /**
* 必含 * 必含
@ -21,7 +28,9 @@ public class MsDocumentAssertionElement {
private Boolean include = false; private Boolean include = false;
/** /**
* 类型 * 类型
* 取值参考 {@link DocumentAssertionType}
*/ */
@EnumValue(enumClass = DocumentAssertionType.class)
private String type; private String type;
/** /**
* 类型校验 * 类型校验
@ -29,7 +38,9 @@ public class MsDocumentAssertionElement {
private Boolean typeVerification = false; private Boolean typeVerification = false;
/** /**
* 匹配条件 * 匹配条件
* 取值参考 {@link MsAssertionCondition}
*/ */
@EnumValue(enumClass = MsAssertionCondition.class)
private String condition; private String condition;
/** /**
* 匹配值 * 匹配值
@ -43,5 +54,28 @@ public class MsDocumentAssertionElement {
/** /**
* 子对象 * 子对象
*/ */
@Valid
private List<MsDocumentAssertionElement> children; private List<MsDocumentAssertionElement> children;
/**
* 文档断言类型
*/
public enum DocumentAssertionType implements ValueEnum {
STRING("string"),
NUMBER("number"),
INTEGER("integer"),
BOOLEAN("boolean"),
ARRAY("array");
private String value;
DocumentAssertionType(String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
}
} }

View File

@ -4,18 +4,27 @@ import lombok.Data;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
/** /**
*
* JSONPath断言 * JSONPath断言
*
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-23 14:04 * @CreateTime: 2023-11-23 14:04
*/ */
@Data @Data
public class MsJSONPathAssertionItem extends MsBodyAssertionItem { public class MsJSONPathAssertionItem extends MsBodyAssertionItem {
/**
* 表达式
*/
private String expression; private String expression;
/**
* 匹配条件
* 取值参考 {@link io.metersphere.sdk.constants.MsAssertionCondition}
*/
private String condition; private String condition;
/**
* 匹配值
*/
private String expectedValue; private String expectedValue;
public boolean isValid() { public boolean isValid() {
return StringUtils.isNotBlank(expression) && StringUtils.isNotBlank(condition) && StringUtils.isNotBlank(expectedValue); return StringUtils.isNotBlank(expression) && StringUtils.isNotBlank(condition) && StringUtils.isNotBlank(expectedValue);
} }

View File

@ -1,5 +1,6 @@
package io.metersphere.api.dto.request.assertion.body; package io.metersphere.api.dto.request.assertion.body;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -14,5 +15,6 @@ public class MsRegexAssertion {
/** /**
* 断言列表 * 断言列表
*/ */
@Valid
private List<MsRegexAssertionItem> assertions; private List<MsRegexAssertionItem> assertions;
} }

View File

@ -10,6 +10,9 @@ import org.apache.commons.lang3.StringUtils;
*/ */
@Data @Data
public class MsRegexAssertionItem extends MsBodyAssertionItem { public class MsRegexAssertionItem extends MsBodyAssertionItem {
/**
* 表达式
*/
private String expression; private String expression;
public boolean isValid() { public boolean isValid() {

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.request.assertion.body; package io.metersphere.api.dto.request.assertion.body;
import io.metersphere.system.valid.EnumValue;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -14,11 +15,12 @@ import java.util.List;
public class MsXPathAssertion { public class MsXPathAssertion {
/** /**
* 响应内容格式 * 响应内容格式
* xml 或者 html * 取值参考 {@link ResponseFormat}
*/ */
@EnumValue(enumClass = ResponseFormat.class)
private String responseFormat; private String responseFormat;
/** /**
* xpath断言 * xpath断言列表
*/ */
private List<MsXPathAssertionItem> assertions; private List<MsXPathAssertionItem> assertions;

View File

@ -11,7 +11,13 @@ import org.apache.commons.lang3.StringUtils;
*/ */
@Data @Data
public class MsXPathAssertionItem extends MsBodyAssertionItem { public class MsXPathAssertionItem extends MsBodyAssertionItem {
/**
* 表达式
*/
private String expression; private String expression;
/**
* 匹配值
*/
private String expectedValue; private String expectedValue;
public boolean isValid() { public boolean isValid() {

View File

@ -3,6 +3,7 @@ package io.metersphere.api.dto.request.http;
import lombok.Data; import lombok.Data;
/** /**
* 请求头
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 16:59 * @CreateTime: 2023-11-06 16:59
*/ */

View File

@ -1,8 +1,10 @@
package io.metersphere.api.dto.request.http; package io.metersphere.api.dto.request.http;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/** /**
* 可以启用禁用的键值对参数
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 17:27 * @CreateTime: 2023-11-06 17:27
*/ */
@ -10,10 +12,12 @@ import lombok.Data;
public class KeyValueEnableParam extends KeyValueParam { public class KeyValueEnableParam extends KeyValueParam {
/** /**
* 是否启用 * 是否启用
* 默认启用
*/ */
private Boolean enable = true; private Boolean enable = true;
/** /**
* 描述 * 描述
*/ */
@Size(max = 500)
private String description; private String description;
} }

View File

@ -1,9 +1,11 @@
package io.metersphere.api.dto.request.http; package io.metersphere.api.dto.request.http;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
/** /**
* 键值对参数
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 17:27 * @CreateTime: 2023-11-06 17:27
*/ */
@ -12,10 +14,12 @@ public class KeyValueParam {
/** /**
* *
*/ */
@Size(max = 100)
private String key; private String key;
/** /**
* *
*/ */
@Size(max = 100)
private String value; private String value;
public boolean isValid() { public boolean isValid() {

View File

@ -0,0 +1,43 @@
package io.metersphere.api.dto.request.http;
import io.metersphere.sdk.constants.ValueEnum;
/**
* 键值对参数的参数类型
* rest 参数和 query 参数
* @Author: jianxing
* @CreateTime: 2024-01-27 11:22
*/
public enum KeyValueParamType implements ValueEnum {
/**
* 字符串类型
* 默认 application/text
*/
STRING("string"),
/**
* 整型
* 默认 application/text
*/
INTEGER("integer"),
/**
* 数值型
* 默认 application/text
*/
NUMBER("number"),
/**
* 数组
* 默认 application/text
*/
ARRAY("array");
private String value;
KeyValueParamType(String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
}

View File

@ -1,16 +1,37 @@
package io.metersphere.api.dto.request.http; package io.metersphere.api.dto.request.http;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/** /**
* http 的其他配置项
*
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-07 10:47 * @CreateTime: 2023-11-07 10:47
*/ */
@Data @Data
public class MsHTTPConfig { public class MsHTTPConfig {
/**
* 连接超时
*/
private Long connectTimeout; private Long connectTimeout;
/**
* 响应超时
*/
private Long responseTimeout; private Long responseTimeout;
/**
* 证书别名
*/
@Size(max = 200)
private String certificateAlias; private String certificateAlias;
/**
* 是否跟随重定向
* 默认 true
*/
private Boolean followRedirects = true; private Boolean followRedirects = true;
/**
* 是否自动重定向
* 默认 false
*/
private Boolean autoRedirects = false; private Boolean autoRedirects = false;
} }

View File

@ -3,50 +3,69 @@ package io.metersphere.api.dto.request.http;
import io.metersphere.api.dto.request.http.auth.HTTPAuth; import io.metersphere.api.dto.request.http.auth.HTTPAuth;
import io.metersphere.api.dto.request.http.body.Body; import io.metersphere.api.dto.request.http.body.Body;
import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.List; import java.util.List;
/**
* Http接口详情
* <pre>
* 其中包括接口调试接口定义接口用例场景的自定义请求 的详情
* 接口协议插件的接口详情也类似
* </pre>
*/
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class MsHTTPElement extends AbstractMsTestElement { public class MsHTTPElement extends AbstractMsTestElement {
// todo 完善字段校验
/** /**
* 完整请求地址 * 完整请求地址
* 自定义请求时使用该字段
*/ */
@Size(max = 500)
private String url; private String url;
/** /**
* 接口定义和用例的请求路径 * 接口定义和用例的请求路径
*/ */
@Size(max = 500)
private String path; private String path;
/** /**
* 请求方法 * 请求方法
*/ */
@NotBlank
@Size(max = 10)
private String method; private String method;
/** /**
* 请求体 * 请求体
*/ */
@Valid
private Body body; private Body body;
/** /**
* 请求头 * 请求头
*/ */
@Valid
private List<Header> headers; private List<Header> headers;
/** /**
* rest参数 * rest参数
*/ */
@Valid
private List<RestParam> rest; private List<RestParam> rest;
/** /**
* query参数 * query参数
*/ */
@Valid
private List<QueryParam> query; private List<QueryParam> query;
/** /**
* 其他配置 * 其他配置
*/ */
@Valid
private MsHTTPConfig otherConfig; private MsHTTPConfig otherConfig;
/** /**
* 认证配置 * 认证配置
*/ */
@Valid
private HTTPAuth authConfig; private HTTPAuth authConfig;
} }

View File

@ -1,8 +1,10 @@
package io.metersphere.api.dto.request.http; package io.metersphere.api.dto.request.http;
import io.metersphere.system.valid.EnumValue;
import lombok.Data; import lombok.Data;
/** /**
* query 参数
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 16:59 * @CreateTime: 2023-11-06 16:59
*/ */
@ -11,10 +13,11 @@ public class QueryParam extends KeyValueEnableParam {
/** /**
* 参数类型 * 参数类型
* 默认string可选integernumberarray * 取值参考 {@link KeyValueParamType}
* todo * 默认String
*/ */
private String paramType; @EnumValue(enumClass = KeyValueParamType.class)
private String paramType = KeyValueParamType.STRING.getValue();
/** /**
* 是否必填 * 是否必填
*/ */
@ -29,6 +32,7 @@ public class QueryParam extends KeyValueEnableParam {
private Integer maxLength; private Integer maxLength;
/** /**
* 是否编码 * 是否编码
* 默认 false
*/ */
private Boolean encode = false; private Boolean encode = false;
} }

View File

@ -1,8 +1,10 @@
package io.metersphere.api.dto.request.http; package io.metersphere.api.dto.request.http;
import io.metersphere.system.valid.EnumValue;
import lombok.Data; import lombok.Data;
/** /**
* rest参数
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 16:59 * @CreateTime: 2023-11-06 16:59
*/ */
@ -10,10 +12,11 @@ import lombok.Data;
public class RestParam extends KeyValueEnableParam { public class RestParam extends KeyValueEnableParam {
/** /**
* 参数类型 * 参数类型
* 默认string可选integernumberarray * 取值参考 {@link KeyValueParamType}
* todo * 默认String
*/ */
private String paramType; @EnumValue(enumClass = KeyValueParamType.class)
private String paramType = KeyValueParamType.STRING.getValue();
/** /**
* 是否必填 * 是否必填
*/ */

View File

@ -5,6 +5,14 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data; import lombok.Data;
/** /**
* http 认证配置
* <pre>
* 该参数传参时需要传入 authType 字段用于区分是哪种认证方式
* authType 取值为:
* BASIC ({@link BasicAuth})
* DIGEST ({@link DigestAuth})
* NONE ({@link NoAuth})
* </pre>
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-07 11:00 * @CreateTime: 2023-11-07 11:00
*/ */

View File

@ -4,11 +4,14 @@ import io.metersphere.api.dto.ApiFile;
import lombok.Data; import lombok.Data;
/** /**
* binary 请求体
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 18:25 * @CreateTime: 2023-11-06 18:25
*/ */
@Data @Data
public class BinaryBody { public class BinaryBody extends ApiFile{
private ApiFile bodyFile; /**
* 描述
*/
private String description; private String description;
} }

View File

@ -1,11 +1,15 @@
package io.metersphere.api.dto.request.http.body; package io.metersphere.api.dto.request.http.body;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* 请求体
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 16:59 * @CreateTime: 2023-11-06 16:59
*/ */
@ -13,18 +17,58 @@ import java.util.Map;
public class Body { public class Body {
/** /**
* 当前选择的请求体类型 * 当前选择的请求体类型
* @see BodyType * 可选值为 {@link BodyType}
* 同时持久化多个类型的请求体 * 同时持久化多个类型的请求体
*/ */
@NotBlank
@Size(max = 20)
private String bodyType; private String bodyType;
/**
* None 请求体
* bodyType NONE 使用该字段
*/
private NoneBody noneBody; private NoneBody noneBody;
/**
* form-data 请求体
* bodyType FORM_DATA 使用该字段
*/
@Valid
private FormDataBody formDataBody; private FormDataBody formDataBody;
/**
* x-www-form-urlencoded 请求体
* bodyType WWW_FORM 使用该字段
*/
@Valid
private WWWFormBody wwwFormBody; private WWWFormBody wwwFormBody;
/**
* json 请求体
* bodyType JSON 使用该字段
*/
@Valid
private JsonBody jsonBody; private JsonBody jsonBody;
/**
* xml 请求体
* bodyType XML 使用该字段
*/
@Valid
private XmlBody xmlBody; private XmlBody xmlBody;
/**
* raw 请求体
* bodyType RAW 使用该字段
*/
@Valid
private RawBody rawBody; private RawBody rawBody;
/**
* binary 请求体
* bodyType BINARY 使用该字段
*/
@Valid
private BinaryBody binaryBody; private BinaryBody binaryBody;
/**
* 请求体类型与请求体类的映射
* 不需要传惨
*/
private static Map<BodyType, Class> bodyTypeClassMap = new HashMap<>(); private static Map<BodyType, Class> bodyTypeClassMap = new HashMap<>();
static { static {
@ -54,13 +98,37 @@ public class Body {
} }
/**
* 请求体类型
*/
public enum BodyType { public enum BodyType {
/**
* 二进制文件
*/
BINARY, BINARY,
/**
* form-data
*/
FORM_DATA, FORM_DATA,
/**
* none
*/
NONE, NONE,
/**
* raw
*/
RAW, RAW,
/**
* x-www-form-urlencoded
*/
WWW_FORM, WWW_FORM,
/**
* xml
*/
XML, XML,
/**
* json
*/
JSON JSON
} }
} }

View File

@ -0,0 +1,57 @@
package io.metersphere.api.dto.request.http.body;
/**
* 请求体键值参数的参数类型
* x-www-form-urlencoded form-data
* @Author: jianxing
* @CreateTime: 2024-01-26 10:59
*/
import io.metersphere.sdk.constants.ValueEnum;
/**
*
*/
public enum BodyParamType implements ValueEnum {
/**
* 字符串类型
* 默认 application/text
*/
STRING("string"),
/**
* 整型
* 默认 application/text
*/
INTEGER("integer"),
/**
* 数值型
* 默认 application/text
*/
NUMBER("number"),
/**
* 数组
* 默认 application/text
*/
ARRAY("array"),
/**
* 文件类型
* 默认 application/octet-stream
*/
FILE("file"),
/**
* json 类型
* 默认 application/json
*/
JSON("json");
private String value;
BodyParamType(String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
}

View File

@ -10,5 +10,8 @@ import java.util.List;
*/ */
@Data @Data
public class FormDataBody { public class FormDataBody {
/**
* form-data 请求体的键值对列表
*/
private List<FormDataKV> fromValues; private List<FormDataKV> fromValues;
} }

View File

@ -1,21 +1,29 @@
package io.metersphere.api.dto.request.http.body; package io.metersphere.api.dto.request.http.body;
import io.metersphere.api.dto.ApiFile; import io.metersphere.api.dto.ApiFile;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.List; import java.util.List;
/** /**
* form-data 请求体的键值对
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 18:11 * @CreateTime: 2023-11-06 18:11
*/ */
@Data @Data
public class FormDataKV extends WWWFormKV { public class FormDataKV extends WWWFormKV {
/**
* 参数的文件列表
* paramType FILE 参数值使用该字段
* 其他类型使用 value字段
*/
@Valid
private List<ApiFile> files; private List<ApiFile> files;
public boolean isFile() { public boolean isFile() {
return StringUtils.equalsIgnoreCase(getParamType(), WWWFormParamType.FILE.name()); return StringUtils.equalsIgnoreCase(getParamType(), BodyParamType.FILE.getValue());
} }
} }

View File

@ -1,9 +1,11 @@
package io.metersphere.api.dto.request.http.body; package io.metersphere.api.dto.request.http.body;
import io.metersphere.api.dto.schema.JsonSchemaItem; import io.metersphere.api.dto.schema.JsonSchemaItem;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
/** /**
* json 请求体
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 18:25 * @CreateTime: 2023-11-06 18:25
*/ */
@ -11,19 +13,23 @@ import lombok.Data;
public class JsonBody { public class JsonBody {
/** /**
* 是否启用 json-schema * 是否启用 json-schema
* 默认false
*/ */
private Boolean enableJsonSchema = false; private Boolean enableJsonSchema = false;
/** /**
* 没有启用 json-schema 时的 json 参数值 * json 参数值
* enableJsonSchema false 时使用该值
*/ */
private String jsonValue; private String jsonValue;
/** /**
* 启用 json-schema 时的参数对象 * 启用 json-schema 时的参数对象
* todo json-schema 编辑器待调研暂时使用 Object 类型 * enableJsonSchema true 时使用该值
*/ */
@Valid
private JsonSchemaItem jsonSchema; private JsonSchemaItem jsonSchema;
/** /**
* 是否开启转换 * 是否开启动态转换
* 默认为 false
*/ */
private Boolean enable = false; private Boolean enableTransition = false;
} }

View File

@ -3,10 +3,14 @@ package io.metersphere.api.dto.request.http.body;
import lombok.Data; import lombok.Data;
/** /**
* raw 请求体
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 18:25 * @CreateTime: 2023-11-06 18:25
*/ */
@Data @Data
public class RawBody { public class RawBody {
/**
* 请求体值
*/
private String value; private String value;
} }

View File

@ -1,14 +1,17 @@
package io.metersphere.api.dto.request.http.body; package io.metersphere.api.dto.request.http.body;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
/** /**
* x-www-form-urlencoded 请求体的键值对列表
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 16:59 * @CreateTime: 2023-11-06 16:59
*/ */
@Data @Data
public class WWWFormBody { public class WWWFormBody {
@Valid
private List<FormDataKV> fromValues; private List<FormDataKV> fromValues;
} }

View File

@ -1,9 +1,13 @@
package io.metersphere.api.dto.request.http.body; package io.metersphere.api.dto.request.http.body;
import io.metersphere.api.dto.request.http.KeyValueEnableParam; import io.metersphere.api.dto.request.http.KeyValueEnableParam;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/** /**
* x-www-form-urlencoded 请求体键值对
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 18:11 * @CreateTime: 2023-11-06 18:11
*/ */
@ -11,28 +15,33 @@ import lombok.Data;
public class WWWFormKV extends KeyValueEnableParam { public class WWWFormKV extends KeyValueEnableParam {
/** /**
* 参数类型 * 参数类型
* * 取值参考 {@link BodyParamType} 中的 value 属性
* @see WWWFormParamType
*/ */
@NotBlank
@Size(max = 20)
@EnumValue(enumClass = BodyParamType.class)
private String paramType; private String paramType;
/**
* 是否必填
* 默认为 false
*/
private Boolean required = false; private Boolean required = false;
/**
* 最小长度
*/
private Integer minLength; private Integer minLength;
/**
* 最大长度
*/
private Integer maxLength; private Integer maxLength;
/**
* 参数的 contentType
*/
@Size(max = 100)
private String contentType; private String contentType;
/**
* 是否对参数进行编码
* 默认 false
*/
private Boolean encode = false; private Boolean encode = false;
enum WWWFormParamType {
/**
* 默认 application/text
*/
STRING, INTEGER, NUMBER, ARRAY,
/**
* 默认 application/octet-stream
*/
FILE,
/**
* 默认 application/json
*/
JSON
}
} }

View File

@ -3,10 +3,14 @@ package io.metersphere.api.dto.request.http.body;
import lombok.Data; import lombok.Data;
/** /**
* xml 请求体
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 18:25 * @CreateTime: 2023-11-06 18:25
*/ */
@Data @Data
public class XmlBody { public class XmlBody {
/**
* 请求体值
*/
private String value; private String value;
} }

View File

@ -7,6 +7,7 @@ import lombok.Data;
import java.util.List; import java.util.List;
/** /**
* 提取处理器配置
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-22 11:08 * @CreateTime: 2023-11-22 11:08
*/ */

View File

@ -2,9 +2,20 @@ package io.metersphere.api.dto.request.processors;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
/** /**
* 前后置处理器配置
* <pre>
* 该参数传参时需要传入 processorType 字段用于区分是哪种认证处理器
* processorType 取值为
* SCRIPT {@link ScriptProcessor}
* SQL {@link SQLProcessor}
* TIME_WAITING {@link TimeWaitingProcessor}
* EXTRACT {@link ExtractPostProcessor}
* <pre>
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-07 10:17 * @CreateTime: 2023-11-07 10:17
*/ */
@ -20,6 +31,8 @@ public abstract class MsProcessor {
/** /**
* 名称 * 名称
*/ */
@NotBlank
@Size(max = 100)
private String name; private String name;
/** /**
* 是否启用 * 是否启用

View File

@ -1,10 +1,12 @@
package io.metersphere.api.dto.request.processors; package io.metersphere.api.dto.request.processors;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
/** /**
* 前后置处理器配置
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-07 10:17 * @CreateTime: 2023-11-07 10:17
*/ */
@ -12,10 +14,12 @@ import java.util.List;
public class MsProcessorConfig { public class MsProcessorConfig {
/** /**
* 是否启用全局前置 * 是否启用全局前置
* 默认为 false
*/ */
private Boolean enableGlobal; private Boolean enableGlobal = false;
/** /**
* 处理器 * 处理器列表
*/ */
@Valid
private List<MsProcessor> processors; private List<MsProcessor> processors;
} }

View File

@ -3,11 +3,15 @@ package io.metersphere.api.dto.request.processors;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.api.dto.request.http.KeyValueEnableParam; import io.metersphere.api.dto.request.http.KeyValueEnableParam;
import io.metersphere.api.dto.request.http.KeyValueParam; import io.metersphere.api.dto.request.http.KeyValueParam;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
/** /**
* SQL 处理器
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-06 21:12 * @CreateTime: 2023-11-06 21:12
*/ */
@ -25,25 +29,32 @@ public class SQLProcessor extends MsProcessor {
/** /**
* 存储结果 * 存储结果
*/ */
@Size(max = 200)
private String resultVariable; private String resultVariable;
/** /**
* 按列存储 * 按列存储
*/ */
@Size(max = 200)
private String variableNames; private String variableNames;
/** /**
* 变量列表 * 变量列表
*/ */
@Valid
private List<KeyValueEnableParam> variables; private List<KeyValueEnableParam> variables;
/** /**
* 环境ID * 环境ID
*/ */
@Size(max = 50)
private String environmentId; private String environmentId;
/** /**
* 数据源ID * 数据源ID
*/ */
@NotBlank
@Size(max = 50)
private String dataSourceId; private String dataSourceId;
/** /**
* 提取参数 * 提取参数
*/ */
@Valid
private List<KeyValueParam> extractParams; private List<KeyValueParam> extractParams;
} }

View File

@ -3,6 +3,8 @@ package io.metersphere.api.dto.request.processors;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.api.dto.request.http.KeyValueParam; import io.metersphere.api.dto.request.http.KeyValueParam;
import io.metersphere.project.constants.ScriptLanguageType; import io.metersphere.project.constants.ScriptLanguageType;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -20,19 +22,23 @@ public class ScriptProcessor extends MsProcessor {
private String script; private String script;
/** /**
* 脚本语言 * 脚本语言
* @see ScriptLanguageType * {@link ScriptLanguageType}
*/ */
@Size(max = 20)
private String scriptLanguage; private String scriptLanguage;
/** /**
* 是否启用公共脚本 * 是否启用公共脚本
* 默认为 false
*/ */
private Boolean enableCommonScript = false; private Boolean enableCommonScript = false;
/** /**
* 脚本ID * 公共脚本ID
*/ */
@Size(max = 50)
private String scriptId; private String scriptId;
/** /**
* 公共脚本入参 * 公共脚本入参
*/ */
@Valid
private List<KeyValueParam> params; private List<KeyValueParam> params;
} }

View File

@ -4,11 +4,16 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Data; import lombok.Data;
/** /**
* 等待时间处理器
* @Author: jianxing * @Author: jianxing
* @CreateTime: 2023-11-07 09:59 * @CreateTime: 2023-11-07 09:59
*/ */
@Data @Data
@JsonTypeName("TIME_WAITING") @JsonTypeName("TIME_WAITING")
public class TimeWaitingProcessor extends MsProcessor { public class TimeWaitingProcessor extends MsProcessor {
/**
* 等待时间
* 单位毫秒
*/
private Integer delay; private Integer delay;
} }

View File

@ -2,9 +2,21 @@ package io.metersphere.api.dto.request.processors.extract;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
/**
* 提取处理器
* <pre>
* 该参数传参时需要传入 extractType 字段用于区分是哪种提取
* extractType 取值为:
* REGEX {@link RegexExtract}
* JSON_PATH {@link JSONPathExtract}
* X_PATH {@link XPathExtract}
* <pre>
*/
@Data @Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "extractType") @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "extractType")
@JsonSubTypes({ @JsonSubTypes({
@ -16,14 +28,19 @@ public abstract class MsExtract {
/** /**
* 变量名 * 变量名
*/ */
@Size(max = 100)
private String variableName; private String variableName;
/** /**
* 参数类型 * 参数类型
* 取值参考 {@link MsExtractType}
*/ */
@Size(max = 100)
@EnumValue(enumClass = MsExtractType.class)
private String variableType; private String variableType;
/** /**
* 表达式 * 表达式
*/ */
@Size(max = 200)
private String expression; private String expression;
/** /**
* 是否启用 * 是否启用
@ -33,4 +50,19 @@ public abstract class MsExtract {
public boolean isValid() { public boolean isValid() {
return StringUtils.isNotBlank(variableName) && StringUtils.isNotBlank(expression); return StringUtils.isNotBlank(variableName) && StringUtils.isNotBlank(expression);
} }
public enum MsExtractType {
/**
* 临时参数
*/
TEMPORARY,
/**
* 环境参数
*/
ENVIRONMENT,
/**
* 全局参数
*/
GLOBAL;
}
} }

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.request.processors.extract; package io.metersphere.api.dto.request.processors.extract;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.system.valid.EnumValue;
import lombok.Data; import lombok.Data;
@Data @Data
@ -8,54 +9,43 @@ import lombok.Data;
public class RegexExtract extends ResultMatchingExtract { public class RegexExtract extends ResultMatchingExtract {
/** /**
* 表达式匹配规则 * 表达式匹配规则
* @see ExpressionRuleType * 取值参考 {@link ExpressionRuleType} 中的 value
* 默认为表达式匹配
*/ */
private String expressionMatchingRule; @EnumValue(enumClass = ExpressionRuleType.class)
private String expressionMatchingRule = ExpressionRuleType.EXPRESSION.name();
/** /**
* 提取范围 * 提取范围
* @see ExtractScope * 取值参考 {@link ExtractScope}
*/ */
@EnumValue(enumClass = ExtractScope.class)
private String extractScope; private String extractScope;
/**
* 表达式匹配规则
*/
public enum ExpressionRuleType { public enum ExpressionRuleType {
/** /**
* 匹配表达式 * 匹配表达式
*/ */
EXPRESSION("$1$"), EXPRESSION,
/** /**
* 匹配组 * 匹配组
*/ */
GROUP("$0$"); GROUP;
private String value;
ExpressionRuleType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
/**
* 提取对象
*/
public enum ExtractScope { public enum ExtractScope {
BODY("false"), BODY,
REQUEST_HEADERS("request_headers"), REQUEST_HEADERS,
UNESCAPED_BODY("unescaped"), UNESCAPED_BODY,
BODY_AS_DOCUMENT("as_document"), BODY_AS_DOCUMENT,
RESPONSE_HEADERS("true"), RESPONSE_HEADERS,
URL("URL"), URL,
RESPONSE_CODE("code"), RESPONSE_CODE,
RESPONSE_MESSAGE("message"); RESPONSE_MESSAGE;
private String value;
ExtractScope(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
} }

View File

@ -1,19 +1,27 @@
package io.metersphere.api.dto.request.processors.extract; package io.metersphere.api.dto.request.processors.extract;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
@Data @Data
public abstract class ResultMatchingExtract extends MsExtract { public abstract class ResultMatchingExtract extends MsExtract {
/** /**
* 结果匹配规则 * 结果匹配规则
* 值为 ResultMatchingRuleType * 取值参考 {@link ResultMatchingRuleType}
* 默认随机匹配
*/ */
private String resultMatchingRule; @Size(max = 100)
@EnumValue(enumClass = ResultMatchingRuleType.class)
private String resultMatchingRule = ResultMatchingRuleType.RANDOM.name();
/** /**
* 匹配第几条结果 * 匹配第几条结果
*/ */
private Integer resultMatchingRuleNum; private Integer resultMatchingRuleNum;
/**
* 结果匹配规则
*/
public enum ResultMatchingRuleType { public enum ResultMatchingRuleType {
/** /**
* 随机匹配 * 随机匹配

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.request.processors.extract; package io.metersphere.api.dto.request.processors.extract;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.system.valid.EnumValue;
import lombok.Data; import lombok.Data;
/** /**
@ -9,6 +10,11 @@ import lombok.Data;
@Data @Data
@JsonTypeName("X_PATH") @JsonTypeName("X_PATH")
public class XPathExtract extends ResultMatchingExtract { public class XPathExtract extends ResultMatchingExtract {
/**
* 提取范围
* 取值参考 {@link ResponseFormat}
*/
@EnumValue(enumClass = ResponseFormat.class)
private String responseFormat; private String responseFormat;
public enum ResponseFormat { public enum ResponseFormat {

View File

@ -1,6 +1,11 @@
package io.metersphere.api.dto.schema; package io.metersphere.api.dto.schema;
import io.metersphere.sdk.constants.ValueEnum;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -8,22 +13,63 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/**
* json-schema 参数项
*/
@Data @Data
public class JsonSchemaItem { public class JsonSchemaItem {
/**
* 示例
*/
private Object example; private Object example;
/**
* 参数ID
*/
@NotBlank
@Size(max = 50)
private String id; private String id;
/**
* 参数名称
*/
@Size(max = 200)
private String title; private String title;
private String type = "string"; /**
* 参数类型
* 取值范围参考 {@link JsonSchemaItemType}
* 默认为 string
*/
@EnumValue(enumClass = JsonSchemaItemType.class)
private String type = JsonSchemaItemType.STRING.value;
/**
* 参数描述
*/
private String description; private String description;
/**
* 子级参数
* type object 或者 array 使用该值
*/
@Valid
private JsonSchemaItem items; private JsonSchemaItem items;
private Map<String, Object> mock; private Map<String, Object> mock;
private Map<String, JsonSchemaItem> properties; private Map<String, JsonSchemaItem> properties;
private JsonSchemaItem additionalProperties; private JsonSchemaItem additionalProperties;
private List<String> required; private List<String> required;
private String pattern; private String pattern;
/**
* 最大长度
*/
private Integer maxLength; private Integer maxLength;
/**
* 最小长度
*/
private Integer minLength; private Integer minLength;
/**
* 最小值
*/
private BigDecimal minimum; private BigDecimal minimum;
/**
* 最大值
*/
private BigDecimal maximum; private BigDecimal maximum;
private String schema; private String schema;
private String format; private String format;
@ -55,4 +101,28 @@ public class JsonSchemaItem {
this.items = new JsonSchemaItem(); this.items = new JsonSchemaItem();
} }
} }
/**
* json-schema 参数类型
*/
enum JsonSchemaItemType implements ValueEnum {
STRING("string"),
NUMBER("number"),
INTEGER("integer"),
BOOLEAN("boolean"),
OBJECT("object"),
ARRAY("array"),
NULL("null");
private String value;
JsonSchemaItemType(String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
}
} }

View File

@ -14,8 +14,7 @@ import org.apache.jmeter.protocol.http.util.HTTPFileArg;
public class MsBinaryBodyConverter extends MsBodyConverter<BinaryBody> { public class MsBinaryBodyConverter extends MsBodyConverter<BinaryBody> {
@Override @Override
public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) { public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) {
ApiFile bodyFile = body.getBodyFile(); HTTPFileArg httpFileArg = getHttpFileArg(body);
HTTPFileArg httpFileArg = getHttpFileArg(bodyFile);
sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg}); sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg});
} }
} }

View File

@ -8,6 +8,8 @@ import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import java.util.HashMap;
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.REGEX_EXTRACTOR_GUI; import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.REGEX_EXTRACTOR_GUI;
/** /**
@ -23,18 +25,42 @@ public class RegexExtractConverter extends ExtractConverter<RegexExtract> {
extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(REGEX_EXTRACTOR_GUI)); extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(REGEX_EXTRACTOR_GUI));
extractor.setRefName(msExtract.getVariableName()); extractor.setRefName(msExtract.getVariableName());
extractor.setRegex(msExtract.getExpression()); extractor.setRegex(msExtract.getExpression());
extractor.setUseField(msExtract.getExtractScope());
extractor.setEnabled(msExtract.getEnable()); extractor.setEnabled(msExtract.getEnable());
extractor.setUseField(getUseField(msExtract.getExtractScope()));
extractor.setTemplate(getTemplate(msExtract.getExpressionMatchingRule()));
// 处理匹配多条等匹配规则 // 处理匹配多条等匹配规则
extractor.setMatchNumber(parseResultMatchingRule(msExtract)); extractor.setMatchNumber(parseResultMatchingRule(msExtract));
// $1$提取 JSON 响应中的第一个匹配项 $0$用于提取整个 JSON 响应
if (StringUtils.isBlank(msExtract.getExpressionMatchingRule())) {
extractor.setTemplate(RegexExtract.ExpressionRuleType.EXPRESSION.getValue());
} else {
extractor.setTemplate(msExtract.getExpressionMatchingRule());
}
hashTree.add(extractor); hashTree.add(extractor);
} }
private String getTemplate(String expressionMatchingRule) {
// $1$提取 JSON 响应中的第一个匹配项 $0$用于提取整个 JSON 响应
HashMap<String, String> ruleValueMap = new HashMap<>() {{
put(RegexExtract.ExpressionRuleType.EXPRESSION.name(), "$1$");
put(RegexExtract.ExpressionRuleType.GROUP.name(), "$0$");
}};
if (StringUtils.isBlank(expressionMatchingRule)) {
return ruleValueMap.get(RegexExtract.ExpressionRuleType.EXPRESSION.name());
} else {
return ruleValueMap.get(expressionMatchingRule);
}
}
private String getUseField(String extractScope) {
HashMap<String, String> extractScopeMap = new HashMap<>() {{
put(RegexExtract.ExtractScope.BODY.name(), "false");
put(RegexExtract.ExtractScope.REQUEST_HEADERS.name(), "request_headers");
put(RegexExtract.ExtractScope.UNESCAPED_BODY.name(), "unescaped");
put(RegexExtract.ExtractScope.BODY_AS_DOCUMENT.name(), "as_document");
put(RegexExtract.ExtractScope.RESPONSE_HEADERS.name(), "true");
put(RegexExtract.ExtractScope.URL.name(), "URL");
put(RegexExtract.ExtractScope.RESPONSE_CODE.name(), "code");
put(RegexExtract.ExtractScope.RESPONSE_MESSAGE.name(), "message");
}};
if (StringUtils.isNotBlank(extractScope)) {
return extractScopeMap.get(extractScope);
} else {
return RegexExtract.ExtractScope.BODY.name();
}
}
} }

View File

@ -24,6 +24,7 @@ import io.metersphere.plugin.api.dto.ParameterConfig;
import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.project.constants.ScriptLanguageType; import io.metersphere.project.constants.ScriptLanguageType;
import io.metersphere.sdk.constants.MsAssertionCondition; import io.metersphere.sdk.constants.MsAssertionCondition;
import io.metersphere.sdk.util.BeanUtils;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -93,10 +94,7 @@ public class MsHTTPElementTest {
xmlBody.setValue("<a/>"); xmlBody.setValue("<a/>");
body.setXmlBody(xmlBody); body.setXmlBody(xmlBody);
BinaryBody binaryBody = new BinaryBody(); body.setBinaryBody(BeanUtils.copyBean(new BinaryBody(), bodyFile));
binaryBody.setBodyFile(bodyFile);
body.setBinaryBody(binaryBody);
return body; return body;
} }