feat(接口测试): 接口调试增删改查接口实现
This commit is contained in:
parent
1e7070bce7
commit
516559506d
|
@ -8,8 +8,9 @@ CREATE TABLE api_debug(
|
||||||
`protocol` VARCHAR(20) NOT NULL COMMENT '接口协议' ,
|
`protocol` VARCHAR(20) NOT NULL COMMENT '接口协议' ,
|
||||||
`method` VARCHAR(20) COMMENT 'http协议类型post/get/其它协议则是协议名(mqtt)' ,
|
`method` VARCHAR(20) COMMENT 'http协议类型post/get/其它协议则是协议名(mqtt)' ,
|
||||||
`path` VARCHAR(500) COMMENT 'http协议路径/其它协议则为空' ,
|
`path` VARCHAR(500) COMMENT 'http协议路径/其它协议则为空' ,
|
||||||
|
`pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序' ,
|
||||||
`project_id` VARCHAR(50) NOT NULL COMMENT '项目fk' ,
|
`project_id` VARCHAR(50) NOT NULL COMMENT '项目fk' ,
|
||||||
`module_id` VARCHAR(50) NOT NULL DEFAULT 'root' COMMENT '模块fk' ,
|
`module_id` VARCHAR(50) NOT NULL DEFAULT 'root' COMMENT '模块fk' ,
|
||||||
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
||||||
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
|
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
|
||||||
`update_time` BIGINT NOT NULL COMMENT '修改时间' ,
|
`update_time` BIGINT NOT NULL COMMENT '修改时间' ,
|
||||||
|
@ -86,7 +87,9 @@ CREATE TABLE api_definition
|
||||||
`delete_time` BIGINT COMMENT '删除时间',
|
`delete_time` BIGINT COMMENT '删除时间',
|
||||||
`deleted` BIT(1) NOT NULL DEFAULT 0 COMMENT '删除状态',
|
`deleted` BIT(1) NOT NULL DEFAULT 0 COMMENT '删除状态',
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
) COMMENT = '接口定义';
|
) ENGINE = InnoDB
|
||||||
|
DEFAULT CHARSET = utf8mb4
|
||||||
|
COLLATE = utf8mb4_general_ci COMMENT = '接口定义';
|
||||||
|
|
||||||
|
|
||||||
CREATE INDEX idx_project_id ON api_definition(project_id);
|
CREATE INDEX idx_project_id ON api_definition(project_id);
|
||||||
|
|
|
@ -2,5 +2,8 @@ package io.metersphere.plugin.api.spi;
|
||||||
|
|
||||||
import io.metersphere.plugin.sdk.spi.AbstractMsPlugin;
|
import io.metersphere.plugin.sdk.spi.AbstractMsPlugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口插件抽象类
|
||||||
|
*/
|
||||||
public abstract class AbstractApiPlugin extends AbstractMsPlugin {
|
public abstract class AbstractApiPlugin extends AbstractMsPlugin {
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.metersphere.plugin.api.spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口协议插件抽象类
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 11:10
|
||||||
|
*/
|
||||||
|
public abstract class AbstractProtocolPlugin extends AbstractApiPlugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回协议名称
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
abstract public String getProtocol();
|
||||||
|
}
|
|
@ -222,11 +222,11 @@ public class PermissionConstants {
|
||||||
|
|
||||||
/*------ start: API_DEBUG ------*/
|
/*------ start: API_DEBUG ------*/
|
||||||
public static final String PROJECT_API_DEBUG_READ = "PROJECT_API_DEBUG:READ";
|
public static final String PROJECT_API_DEBUG_READ = "PROJECT_API_DEBUG:READ";
|
||||||
public static final String PROJECT_API_DEBUG_READ_ADD = "PROJECT_API_DEBUG:READ+ADD";
|
public static final String PROJECT_API_DEBUG_ADD = "PROJECT_API_DEBUG:READ+ADD";
|
||||||
public static final String PROJECT_API_DEBUG_READ_UPDATE = "PROJECT_API_DEBUG:READ+UPDATE";
|
public static final String PROJECT_API_DEBUG_UPDATE = "PROJECT_API_DEBUG:READ+UPDATE";
|
||||||
public static final String PROJECT_API_DEBUG_READ_DELETE = "PROJECT_API_DEBUG:READ+DELETE";
|
public static final String PROJECT_API_DEBUG_DELETE = "PROJECT_API_DEBUG:READ+DELETE";
|
||||||
public static final String PROJECT_API_DEBUG_READ_IMPORT = "PROJECT_API_DEBUG:READ+IMPORT";
|
public static final String PROJECT_API_DEBUG_IMPORT = "PROJECT_API_DEBUG:READ+IMPORT";
|
||||||
public static final String PROJECT_API_DEBUG_READ_EXECUTE = "PROJECT_API_DEBUG:READ+EXECUTE";
|
public static final String PROJECT_API_DEBUG_EXECUTE = "PROJECT_API_DEBUG:READ+EXECUTE";
|
||||||
/*------ end: API_DEBUG ------*/
|
/*------ end: API_DEBUG ------*/
|
||||||
|
|
||||||
/*------ start: BUG ------*/
|
/*------ start: BUG ------*/
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 16:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Header extends KeyValueParam {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 17:27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class KeyValueParam {
|
||||||
|
/**
|
||||||
|
* 键
|
||||||
|
*/
|
||||||
|
private String key;
|
||||||
|
/**
|
||||||
|
* 值
|
||||||
|
*/
|
||||||
|
private String value;
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private Boolean enable = true;
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 10:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MsHTTPConfig {
|
||||||
|
private Long connectTimeout;
|
||||||
|
private Long responseTimeout;
|
||||||
|
private String certificateAlias;
|
||||||
|
private Boolean followRedirects = true;
|
||||||
|
private Boolean autoRedirects = false;
|
||||||
|
}
|
|
@ -1,11 +1,62 @@
|
||||||
package io.metersphere.sdk.dto.api.request.http;
|
package io.metersphere.sdk.dto.api.request.http;
|
||||||
|
|
||||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.auth.HTTPAuth;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.body.Body;
|
||||||
|
import io.metersphere.sdk.dto.api.request.processors.MsProcessor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class MsHTTPElement extends AbstractMsTestElement {
|
public class MsHTTPElement extends AbstractMsTestElement {
|
||||||
private String domain;
|
// todo 完善字段校验
|
||||||
|
/**
|
||||||
|
* 完整请求地址
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
/**
|
||||||
|
* 接口定义和用例的请求路径
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
/**
|
||||||
|
* 请求方法
|
||||||
|
*/
|
||||||
|
private String method;
|
||||||
|
/**
|
||||||
|
* 请求体
|
||||||
|
*/
|
||||||
|
private Body body;
|
||||||
|
/**
|
||||||
|
* 请求头
|
||||||
|
*/
|
||||||
|
private List<Header> headers;
|
||||||
|
/**
|
||||||
|
* rest参数
|
||||||
|
*/
|
||||||
|
private List<RestParam> rest;
|
||||||
|
/**
|
||||||
|
* query参数
|
||||||
|
*/
|
||||||
|
private List<QueryParam> query;
|
||||||
|
/**
|
||||||
|
* 其他配置
|
||||||
|
*/
|
||||||
|
private MsHTTPConfig otherConfig;
|
||||||
|
/**
|
||||||
|
* 认证配置
|
||||||
|
*/
|
||||||
|
private HTTPAuth authConfig;
|
||||||
|
/**
|
||||||
|
* 前置处理器
|
||||||
|
*/
|
||||||
|
private List<MsProcessor> preProcessors;
|
||||||
|
/**
|
||||||
|
* 后置处理器
|
||||||
|
*/
|
||||||
|
private List<MsProcessor> postProcessors;
|
||||||
|
// todo 断言和提取 待设计
|
||||||
}
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 16:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class QueryParam extends KeyValueParam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数类型
|
||||||
|
* 默认string,可选integer、number、array
|
||||||
|
* todo
|
||||||
|
*/
|
||||||
|
private String paramType;
|
||||||
|
/**
|
||||||
|
* 是否必填
|
||||||
|
*/
|
||||||
|
private Boolean required = false;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 16:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RestParam extends KeyValueParam {
|
||||||
|
/**
|
||||||
|
* 参数类型
|
||||||
|
* 默认string,可选integer、number、array
|
||||||
|
* todo
|
||||||
|
*/
|
||||||
|
private String paramType;
|
||||||
|
/**
|
||||||
|
* 是否必填
|
||||||
|
*/
|
||||||
|
private Boolean required = false;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.auth;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 11:00
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("BASIC")
|
||||||
|
public class BasicAuth extends HTTPAuth {
|
||||||
|
private String userName;
|
||||||
|
private String password;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.auth;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 11:00
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("DIGEST")
|
||||||
|
public class DigestAuth extends HTTPAuth {
|
||||||
|
private String userName;
|
||||||
|
private String password;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.auth;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 11:00
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "authType")
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = NoAuth.class),
|
||||||
|
@JsonSubTypes.Type(value = BasicAuth.class),
|
||||||
|
@JsonSubTypes.Type(value = DigestAuth.class),
|
||||||
|
})
|
||||||
|
public abstract class HTTPAuth {
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.auth;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 11:00
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("NONE")
|
||||||
|
public class NoAuth extends HTTPAuth {
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 18:25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("BINARY")
|
||||||
|
public class BinaryBody extends Body {
|
||||||
|
// todo 如果fileName能直接定义到文件,就不需要filePath
|
||||||
|
private String filePath;
|
||||||
|
private String fileName;
|
||||||
|
private String description;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 16:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "bodyType")
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = NoneBody.class),
|
||||||
|
@JsonSubTypes.Type(value = FormDataBody.class),
|
||||||
|
@JsonSubTypes.Type(value = WWWFormBody.class),
|
||||||
|
@JsonSubTypes.Type(value = JsonBody.class),
|
||||||
|
@JsonSubTypes.Type(value = XmlBody.class),
|
||||||
|
@JsonSubTypes.Type(value = RawBody.class),
|
||||||
|
@JsonSubTypes.Type(value = BinaryBody.class)
|
||||||
|
})
|
||||||
|
public abstract class Body {
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 16:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("FORM_DATA")
|
||||||
|
public class FormDataBody extends Body {
|
||||||
|
private List<FormDataKV> fromValues;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.KeyValueParam;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 18:11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class FormDataKV extends KeyValueParam {
|
||||||
|
private String paramType;
|
||||||
|
private Boolean required = false;
|
||||||
|
private Integer minLength;
|
||||||
|
private Integer maxLength;
|
||||||
|
private String contentType;
|
||||||
|
private Boolean encode = false;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 18:25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("JSON")
|
||||||
|
public class JsonBody extends Body {
|
||||||
|
private String value;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 18:25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("NONE")
|
||||||
|
public class NoneBody extends Body {
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 18:25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("RAW")
|
||||||
|
public class RawBody extends Body {
|
||||||
|
private String value;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 16:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("WWW_FORM")
|
||||||
|
public class WWWFormBody extends Body {
|
||||||
|
private List<FormDataKV> fromValues;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.http.body;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 18:25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("XML")
|
||||||
|
public class XmlBody extends Body {
|
||||||
|
private String value;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.processors;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 10:17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "processorType")
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = ScriptProcessor.class),
|
||||||
|
@JsonSubTypes.Type(value = SQLProcessor.class),
|
||||||
|
@JsonSubTypes.Type(value = TimeWaitingProcessor.class),
|
||||||
|
})
|
||||||
|
public abstract class MsProcessor {
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.processors;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.KeyValueParam;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 21:12
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("SQL")
|
||||||
|
public class SQLProcessor extends MsProcessor {
|
||||||
|
/**
|
||||||
|
* 脚本内容
|
||||||
|
*/
|
||||||
|
private String script;
|
||||||
|
/**
|
||||||
|
* 超时时间
|
||||||
|
*/
|
||||||
|
private long queryTimeout;
|
||||||
|
/**
|
||||||
|
* 存储结果
|
||||||
|
*/
|
||||||
|
private String resultVariable;
|
||||||
|
/**
|
||||||
|
* 按列存储
|
||||||
|
*/
|
||||||
|
private String variableNames;
|
||||||
|
/**
|
||||||
|
* 变量列表
|
||||||
|
*/
|
||||||
|
private List<KeyValueParam> variables;
|
||||||
|
/**
|
||||||
|
* 环境ID
|
||||||
|
*/
|
||||||
|
private String environmentId;
|
||||||
|
/**
|
||||||
|
* 数据源ID
|
||||||
|
*/
|
||||||
|
private String dataSourceId;
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private Boolean enable;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.processors;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 21:12
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("SCRIPT")
|
||||||
|
public class ScriptProcessor extends MsProcessor {
|
||||||
|
private String script;
|
||||||
|
private String scriptLanguage;
|
||||||
|
private Boolean jsrEnable;
|
||||||
|
private Boolean enable;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.metersphere.sdk.dto.api.request.processors;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 09:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@JsonTypeName("TIME_WAITING")
|
||||||
|
public class TimeWaitingProcessor extends MsProcessor {
|
||||||
|
private Integer delay;
|
||||||
|
private Boolean enable;
|
||||||
|
}
|
|
@ -283,3 +283,6 @@ api_environment_config.id.not_blank=ID不能为空
|
||||||
api_environment_config.environment_id.length_range=环境ID长度必须在1-50之间
|
api_environment_config.environment_id.length_range=环境ID长度必须在1-50之间
|
||||||
api_environment_config.environment_id.not_blank=环境ID不能为空
|
api_environment_config.environment_id.not_blank=环境ID不能为空
|
||||||
api_module.not.exist=模块不存在
|
api_module.not.exist=模块不存在
|
||||||
|
|
||||||
|
permission.api.name=接口测试
|
||||||
|
api_debug_exist=接口已存在
|
|
@ -267,6 +267,11 @@ api_debug.project_id.not_blank=Project ID cannot be blank
|
||||||
api_debug.project_id.length_range=Project ID length must be between 1-50
|
api_debug.project_id.length_range=Project ID length must be between 1-50
|
||||||
api_debug.module_id.not_blank=Module ID cannot be blank
|
api_debug.module_id.not_blank=Module ID cannot be blank
|
||||||
api_debug.module_id.length_range=Module ID length must be between 1-50
|
api_debug.module_id.length_range=Module ID length must be between 1-50
|
||||||
|
api_debug.create_user.not_blank=The creator cannot be empty
|
||||||
|
api_debug.create_user.length_range=Creator length must be between {min}-{max}
|
||||||
|
api_debug.update_user.not_blank=Modifier cannot be blank
|
||||||
|
api_debug.update_user.length_range=Modifier length must be between {min}-{max}
|
||||||
|
|
||||||
#module: ApiDebugModule
|
#module: ApiDebugModule
|
||||||
api_debug_module.id.not_blank=ID cannot be blank
|
api_debug_module.id.not_blank=ID cannot be blank
|
||||||
api_debug_module.id.length_range=Module ID length must be between 1-50
|
api_debug_module.id.length_range=Module ID length must be between 1-50
|
||||||
|
@ -282,7 +287,10 @@ api_debug_module.unplanned_request=Unplanned request
|
||||||
api_unplanned_request=Unplanned Api
|
api_unplanned_request=Unplanned Api
|
||||||
|
|
||||||
#module: ApiEnvironmentConfig
|
#module: ApiEnvironmentConfig
|
||||||
api_environment_config.id.not_blank=ID不能为空
|
api_environment_config.id.not_blank=ID cannot be blank
|
||||||
api_environment_config.environment_id.length_range=环境ID长度必须在1-50之间
|
api_environment_config.environment_id.length_range=Environment ID length must be between 1-50
|
||||||
api_environment_config.environment_id.not_blank=环境ID不能为空
|
api_environment_config.environment_id.not_blank=Environment ID cannot be blank
|
||||||
api_module.not.exist=模块不存在
|
api_module.not.exist=The module does not exist
|
||||||
|
|
||||||
|
permission.api.name=API Test
|
||||||
|
api_debug_exist=The API already exists
|
|
@ -267,6 +267,11 @@ api_debug.project_id.not_blank=项目ID不能为空
|
||||||
api_debug.project_id.length_range=项目ID长度必须在1-50之间
|
api_debug.project_id.length_range=项目ID长度必须在1-50之间
|
||||||
api_debug.module_id.not_blank=模块ID不能为空
|
api_debug.module_id.not_blank=模块ID不能为空
|
||||||
api_debug.module_id.length_range=模块ID长度必须在1-50之间
|
api_debug.module_id.length_range=模块ID长度必须在1-50之间
|
||||||
|
api_debug.create_user.not_blank=创建人不能为空
|
||||||
|
api_debug.create_user.length_range=创建人长度必须在{min}和{max}之间
|
||||||
|
api_debug.update_user.not_blank=修改人不能为空
|
||||||
|
api_debug.update_user.length_range=修改人长度必须在{min}和{max}之间
|
||||||
|
|
||||||
#module: ApiDebugModule
|
#module: ApiDebugModule
|
||||||
api_debug_module.id.not_blank=ID不能为空
|
api_debug_module.id.not_blank=ID不能为空
|
||||||
api_debug_module.id.length_range=模块ID长度必须在1-50之间
|
api_debug_module.id.length_range=模块ID长度必须在1-50之间
|
||||||
|
@ -285,4 +290,7 @@ api_unplanned_request=未规划接口
|
||||||
api_environment_config.id.not_blank=ID不能为空
|
api_environment_config.id.not_blank=ID不能为空
|
||||||
api_environment_config.environment_id.length_range=环境ID长度必须在1-50之间
|
api_environment_config.environment_id.length_range=环境ID长度必须在1-50之间
|
||||||
api_environment_config.environment_id.not_blank=环境ID不能为空
|
api_environment_config.environment_id.not_blank=环境ID不能为空
|
||||||
api_module.not.exist=模块不存在
|
api_module.not.exist=模块不存在
|
||||||
|
|
||||||
|
permission.api.name=接口测试
|
||||||
|
api_debug_exist=接口已存在
|
|
@ -267,6 +267,11 @@ api_debug.project_id.not_blank=項目ID不能為空
|
||||||
api_debug.project_id.length_range=項目ID長度必須在1-50之間
|
api_debug.project_id.length_range=項目ID長度必須在1-50之間
|
||||||
api_debug.module_id.not_blank=模塊ID不能為空
|
api_debug.module_id.not_blank=模塊ID不能為空
|
||||||
api_debug.module_id.length_range=模塊ID長度必須在1-50之間
|
api_debug.module_id.length_range=模塊ID長度必須在1-50之間
|
||||||
|
api_debug.create_user.not_blank=創建人不能為空
|
||||||
|
api_debug.create_user.length_range=創建人長度必須在{min}和{max}之間
|
||||||
|
api_debug.update_user.not_blank=修改人不能為空
|
||||||
|
api_debug.update_user.length_range=修改人長度必須在{min}和{max}之間
|
||||||
|
|
||||||
#module: ApiDebugModule
|
#module: ApiDebugModule
|
||||||
api_debug_module.id.not_blank=ID不能為空
|
api_debug_module.id.not_blank=ID不能為空
|
||||||
api_debug_module.id.length_range=模塊ID長度必須在1-50之間
|
api_debug_module.id.length_range=模塊ID長度必須在1-50之間
|
||||||
|
@ -285,4 +290,7 @@ api_unplanned_request=未规划接口
|
||||||
api_environment_config.id.not_blank=ID不能為空
|
api_environment_config.id.not_blank=ID不能為空
|
||||||
api_environment_config.environment_id.length_range=環境ID長度必須在1-50之間
|
api_environment_config.environment_id.length_range=環境ID長度必須在1-50之間
|
||||||
api_environment_config.environment_id.not_blank=環境ID不能為空
|
api_environment_config.environment_id.not_blank=環境ID不能為空
|
||||||
api_module.not.exist=模塊不存在
|
api_module.not.exist=模塊不存在
|
||||||
|
|
||||||
|
permission.api.name=接口測試
|
||||||
|
api_debug_exist=接口已存在
|
|
@ -439,6 +439,7 @@ permission.delete=删除
|
||||||
permission.import=导入
|
permission.import=导入
|
||||||
permission.recover=恢复
|
permission.recover=恢复
|
||||||
permission.export=导出
|
permission.export=导出
|
||||||
|
permission.execute=执行
|
||||||
|
|
||||||
file_name_illegal_error=文件名不合法
|
file_name_illegal_error=文件名不合法
|
||||||
plugin_enable_error=插件未启用
|
plugin_enable_error=插件未启用
|
||||||
|
|
|
@ -441,6 +441,7 @@ permission.delete=Delete
|
||||||
permission.import=Import
|
permission.import=Import
|
||||||
permission.recover=Recover
|
permission.recover=Recover
|
||||||
permission.export=Export
|
permission.export=Export
|
||||||
|
permission.execute=Execute
|
||||||
|
|
||||||
file_name_illegal_error=File name is illegal
|
file_name_illegal_error=File name is illegal
|
||||||
plugin_enable_error=Plugin is not enabled
|
plugin_enable_error=Plugin is not enabled
|
||||||
|
|
|
@ -439,6 +439,7 @@ permission.delete=删除
|
||||||
permission.import=导入
|
permission.import=导入
|
||||||
permission.recover=恢复
|
permission.recover=恢复
|
||||||
permission.export=导出
|
permission.export=导出
|
||||||
|
permission.execute=执行
|
||||||
|
|
||||||
file_name_illegal_error=文件名不合法
|
file_name_illegal_error=文件名不合法
|
||||||
plugin_enable_error=插件未启用
|
plugin_enable_error=插件未启用
|
||||||
|
|
|
@ -437,6 +437,7 @@ permission.delete=刪除
|
||||||
permission.import=導入
|
permission.import=導入
|
||||||
permission.recover=恢復
|
permission.recover=恢復
|
||||||
permission.export=導出
|
permission.export=導出
|
||||||
|
permission.execute=執行
|
||||||
|
|
||||||
file_name_illegal_error=文件名不合法
|
file_name_illegal_error=文件名不合法
|
||||||
plugin_enable_error=插件未啟用
|
plugin_enable_error=插件未啟用
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package io.metersphere.api.controller.debug;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiDebug;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugAddRequest;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugDTO;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugSimpleDTO;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugUpdateRequest;
|
||||||
|
import io.metersphere.api.service.debug.ApiDebugLogService;
|
||||||
|
import io.metersphere.api.service.debug.ApiDebugService;
|
||||||
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
|
import io.metersphere.system.log.annotation.Log;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
|
import io.metersphere.system.utils.SessionUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : jianxing
|
||||||
|
* @date : 2023-11-6
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/debug")
|
||||||
|
@Tag(name = "接口调试")
|
||||||
|
public class ApiDebugController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApiDebugService apiDebugService;
|
||||||
|
|
||||||
|
@GetMapping("/list/{protocol}")
|
||||||
|
@Operation(summary = "获取接口调试列表")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_READ)
|
||||||
|
public List<ApiDebugSimpleDTO> list(@PathVariable String protocol) {
|
||||||
|
return apiDebugService.list(protocol, SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get/{id}")
|
||||||
|
@Operation(summary = "获取接口调试详情")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_READ)
|
||||||
|
public ApiDebugDTO get(@PathVariable String id) {
|
||||||
|
return apiDebugService.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/add")
|
||||||
|
@Operation(summary = "创建接口调试")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_ADD)
|
||||||
|
@Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = ApiDebugLogService.class)
|
||||||
|
public ApiDebug add(@Validated @RequestBody ApiDebugAddRequest request) {
|
||||||
|
return apiDebugService.add(request, SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/update")
|
||||||
|
@Operation(summary = "更新接口调试")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_UPDATE)
|
||||||
|
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = ApiDebugLogService.class)
|
||||||
|
public ApiDebug update(@Validated @RequestBody ApiDebugUpdateRequest request) {;
|
||||||
|
return apiDebugService.update(request, SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/delete/{id}")
|
||||||
|
@Operation(summary = "删除接口调试")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_DELETE)
|
||||||
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = ApiDebugLogService.class)
|
||||||
|
public void delete(@PathVariable String id) {
|
||||||
|
apiDebugService.delete(id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,14 +35,14 @@ public class ApiDebugModuleController {
|
||||||
|
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@Operation(summary = "接口测试-接口调试-模块-添加模块")
|
@Operation(summary = "接口测试-接口调试-模块-添加模块")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_READ_ADD)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_ADD)
|
||||||
public String add(@RequestBody @Validated ModuleCreateRequest request) {
|
public String add(@RequestBody @Validated ModuleCreateRequest request) {
|
||||||
return apiDebugModuleService.add(request, SessionUtils.getUserId());
|
return apiDebugModuleService.add(request, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/update")
|
@PostMapping("/update")
|
||||||
@Operation(summary = "接口测试-接口调试-模块-修改模块")
|
@Operation(summary = "接口测试-接口调试-模块-修改模块")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_READ_UPDATE)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_UPDATE)
|
||||||
public boolean list(@RequestBody @Validated ModuleUpdateRequest request) {
|
public boolean list(@RequestBody @Validated ModuleUpdateRequest request) {
|
||||||
apiDebugModuleService.update(request, SessionUtils.getUserId(), SessionUtils.getCurrentProjectId());
|
apiDebugModuleService.update(request, SessionUtils.getUserId(), SessionUtils.getCurrentProjectId());
|
||||||
return true;
|
return true;
|
||||||
|
@ -50,14 +50,14 @@ public class ApiDebugModuleController {
|
||||||
|
|
||||||
@GetMapping("/delete/{deleteId}")
|
@GetMapping("/delete/{deleteId}")
|
||||||
@Operation(summary = "接口测试-接口调试-模块-删除模块")
|
@Operation(summary = "接口测试-接口调试-模块-删除模块")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_READ_DELETE)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_DELETE)
|
||||||
public void deleteNode(@PathVariable String deleteId) {
|
public void deleteNode(@PathVariable String deleteId) {
|
||||||
apiDebugModuleService.deleteModule(deleteId, SessionUtils.getUserId());
|
apiDebugModuleService.deleteModule(deleteId, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/move")
|
@PostMapping("/move")
|
||||||
@Operation(summary = "接口测试-接口调试-模块-移动模块")
|
@Operation(summary = "接口测试-接口调试-模块-移动模块")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_READ_UPDATE)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_DEBUG_UPDATE)
|
||||||
public void moveNode(@Validated @RequestBody NodeMoveRequest request) {
|
public void moveNode(@Validated @RequestBody NodeMoveRequest request) {
|
||||||
apiDebugModuleService.moveNode(request, SessionUtils.getUserId());
|
apiDebugModuleService.moveNode(request, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package io.metersphere.api.controller.result;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.exception.IResultCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jianxing
|
||||||
|
*/
|
||||||
|
public enum ApiResultCode implements IResultCode {
|
||||||
|
|
||||||
|
API_DEBUG_EXIST(104001, "api_debug_exist");
|
||||||
|
|
||||||
|
|
||||||
|
private final int code;
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
ApiResultCode(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return getTranslationMessage(this.message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package io.metersphere.api.dto.debug;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 10:22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ApiDebugAddRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.name.not_blank}")
|
||||||
|
@Size(min = 1, max = 255, message = "{api_debug.name.length_range}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "接口协议", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.protocol.not_blank}")
|
||||||
|
@Size(min = 1, max = 20, message = "{api_debug.protocol.length_range}")
|
||||||
|
private String protocol;
|
||||||
|
|
||||||
|
@Schema(description = "http协议类型post/get/其它协议则是协议名(mqtt)")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
@Schema(description = "http协议url/其它协议则为空")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@Schema(description = "项目fk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.project_id.not_blank}")
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.project_id.length_range}")
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "模块fk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.module_id.not_blank}")
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.module_id.length_range}")
|
||||||
|
private String moduleId;
|
||||||
|
|
||||||
|
@Schema(description = "请求内容")
|
||||||
|
@NotBlank
|
||||||
|
private String request;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.metersphere.api.dto.debug;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiDebug;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ApiDebugDTO extends ApiDebug {
|
||||||
|
@Schema(description = "请求内容")
|
||||||
|
private AbstractMsTestElement request;
|
||||||
|
|
||||||
|
@Schema(description = "响应内容")
|
||||||
|
private String response;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.api.dto.debug;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ApiDebugSimpleDTO {
|
||||||
|
@Schema(description = "接口ID")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "接口名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "http协议类型post/get/其它协议则是协议名(mqtt)")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
@Schema(description = "模块fk")
|
||||||
|
private String moduleId;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package io.metersphere.api.dto.debug;
|
||||||
|
|
||||||
|
import io.metersphere.validation.groups.Created;
|
||||||
|
import io.metersphere.validation.groups.Updated;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-06 10:22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ApiDebugUpdateRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "接口pk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.id.not_blank}", groups = {Updated.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.id.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.name.not_blank}", groups = {Created.class})
|
||||||
|
@Size(min = 1, max = 255, message = "{api_debug.name.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "http协议类型post/get/其它协议则是协议名(mqtt)")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
@Schema(description = "http协议路径/其它协议则为空")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@Schema(description = "模块fk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.module_id.not_blank}", groups = {Created.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.module_id.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String moduleId;
|
||||||
|
|
||||||
|
@Schema(description = "请求内容")
|
||||||
|
@NotBlank
|
||||||
|
private String request;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package io.metersphere.api.mapper;
|
||||||
|
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugSimpleDTO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jianxing
|
||||||
|
* @date : 2023-11-6
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ExtApiDebugMapper {
|
||||||
|
List<ApiDebugSimpleDTO> list(@Param("protocol") String protocol, @Param("userId") String userId);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="io.metersphere.api.mapper.ExtApiDebugMapper">
|
||||||
|
|
||||||
|
<select id="list" resultType="io.metersphere.api.dto.debug.ApiDebugSimpleDTO">
|
||||||
|
select id, name, method, module_id
|
||||||
|
from api_debug
|
||||||
|
where protocol = #{protocol} and create_user = #{userId}
|
||||||
|
ORDER BY pos
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -0,0 +1,68 @@
|
||||||
|
package io.metersphere.api.service.debug;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiDebug;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugAddRequest;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugUpdateRequest;
|
||||||
|
import io.metersphere.sdk.constants.OperationLogConstants;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogModule;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
|
import io.metersphere.system.log.dto.LogDTO;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
/**
|
||||||
|
* @author jianxing
|
||||||
|
* @date : 2023-11-6
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class ApiDebugLogService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApiDebugService apiDebugService;
|
||||||
|
|
||||||
|
public LogDTO addLog(ApiDebugAddRequest request) {
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
request.getProjectId(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
OperationLogType.ADD.name(),
|
||||||
|
OperationLogModule.API_DEBUG,
|
||||||
|
request.getName());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(request));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogDTO updateLog(ApiDebugUpdateRequest request) {
|
||||||
|
ApiDebug apiDebug = apiDebugService.get(request.getId());
|
||||||
|
LogDTO dto = null;
|
||||||
|
if (apiDebug != null) {
|
||||||
|
dto = new LogDTO(
|
||||||
|
apiDebug.getProjectId(),
|
||||||
|
null,
|
||||||
|
apiDebug.getId(),
|
||||||
|
null,
|
||||||
|
OperationLogType.UPDATE.name(),
|
||||||
|
OperationLogModule.API_DEBUG,
|
||||||
|
apiDebug.getName());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(apiDebug));
|
||||||
|
}
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogDTO deleteLog(String id) {
|
||||||
|
ApiDebug apiDebug = apiDebugService.get(id);
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
OperationLogConstants.SYSTEM,
|
||||||
|
OperationLogConstants.SYSTEM,
|
||||||
|
apiDebug.getId(),
|
||||||
|
null,
|
||||||
|
OperationLogType.DELETE.name(),
|
||||||
|
OperationLogModule.API_DEBUG,
|
||||||
|
apiDebug.getName());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(apiDebug));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
package io.metersphere.api.service.debug;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiDebug;
|
||||||
|
import io.metersphere.api.domain.ApiDebugBlob;
|
||||||
|
import io.metersphere.api.domain.ApiDebugExample;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugAddRequest;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugDTO;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugSimpleDTO;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugUpdateRequest;
|
||||||
|
import io.metersphere.api.mapper.ApiDebugBlobMapper;
|
||||||
|
import io.metersphere.api.mapper.ApiDebugMapper;
|
||||||
|
import io.metersphere.api.mapper.ExtApiDebugMapper;
|
||||||
|
import io.metersphere.api.util.ApiDataUtils;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.metersphere.project.service.ProjectService;
|
||||||
|
import io.metersphere.sdk.exception.MSException;
|
||||||
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
|
import io.metersphere.system.utils.ServiceUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static io.metersphere.api.controller.result.ApiResultCode.API_DEBUG_EXIST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jianxing
|
||||||
|
* @date : 2023-11-6
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class ApiDebugService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApiDebugMapper apiDebugMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiDebugBlobMapper apiDebugBlobMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtApiDebugMapper extApiDebugMapper;
|
||||||
|
|
||||||
|
public List<ApiDebugSimpleDTO> list(String protocol, String userId) {
|
||||||
|
return extApiDebugMapper.list(protocol, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiDebugDTO get(String id) {
|
||||||
|
checkResourceExist(id);
|
||||||
|
ApiDebug apiDebug = apiDebugMapper.selectByPrimaryKey(id);
|
||||||
|
ApiDebugBlob apiDebugBlob = apiDebugBlobMapper.selectByPrimaryKey(id);
|
||||||
|
ApiDebugDTO apiDebugDTO = new ApiDebugDTO();
|
||||||
|
BeanUtils.copyBean(apiDebugDTO, apiDebug);
|
||||||
|
apiDebugDTO.setRequest(ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class));
|
||||||
|
apiDebugDTO.setResponse(apiDebugDTO.getResponse());
|
||||||
|
return apiDebugDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiDebug add(ApiDebugAddRequest request, String createUser) {
|
||||||
|
ProjectService.checkResourceExist(request.getProjectId());
|
||||||
|
ApiDebug apiDebug = new ApiDebug();
|
||||||
|
BeanUtils.copyBean(apiDebug, request);
|
||||||
|
apiDebug.setCreateUser(createUser);
|
||||||
|
checkAddExist(apiDebug);
|
||||||
|
apiDebug.setId(IDGenerator.nextStr());
|
||||||
|
apiDebug.setCreateTime(System.currentTimeMillis());
|
||||||
|
apiDebug.setUpdateTime(System.currentTimeMillis());
|
||||||
|
apiDebug.setUpdateUser(apiDebug.getCreateUser());
|
||||||
|
apiDebugMapper.insert(apiDebug);
|
||||||
|
|
||||||
|
// todo 处理 body 文件
|
||||||
|
// todo 校验 moduleId
|
||||||
|
|
||||||
|
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||||
|
apiDebugBlob.setId(apiDebug.getId());
|
||||||
|
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
||||||
|
apiDebugBlobMapper.insert(apiDebugBlob);
|
||||||
|
return apiDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiDebug update(ApiDebugUpdateRequest request, String updateUser) {
|
||||||
|
checkResourceExist(request.getId());
|
||||||
|
ApiDebug apiDebug = BeanUtils.copyBean(new ApiDebug(), request);
|
||||||
|
ApiDebug originApiDebug = apiDebugMapper.selectByPrimaryKey(request.getId());
|
||||||
|
checkUpdateExist(apiDebug, originApiDebug);
|
||||||
|
apiDebug.setUpdateUser(updateUser);
|
||||||
|
apiDebug.setUpdateTime(System.currentTimeMillis());
|
||||||
|
apiDebugMapper.updateByPrimaryKeySelective(apiDebug);
|
||||||
|
|
||||||
|
// todo 处理 body 文件
|
||||||
|
// todo 校验 moduleId
|
||||||
|
|
||||||
|
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||||
|
apiDebugBlob.setId(request.getId());
|
||||||
|
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
||||||
|
apiDebugBlobMapper.updateByPrimaryKeySelective(apiDebugBlob);
|
||||||
|
return apiDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(String id) {
|
||||||
|
checkResourceExist(id);
|
||||||
|
apiDebugMapper.deleteByPrimaryKey(id);
|
||||||
|
apiDebugBlobMapper.deleteByPrimaryKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAddExist(ApiDebug apiDebug) {
|
||||||
|
ApiDebugExample example = new ApiDebugExample();
|
||||||
|
example.createCriteria()
|
||||||
|
.andNameEqualTo(apiDebug.getName())
|
||||||
|
.andModuleIdEqualTo(apiDebug.getModuleId());
|
||||||
|
if (CollectionUtils.isNotEmpty(apiDebugMapper.selectByExample(example))) {
|
||||||
|
throw new MSException(API_DEBUG_EXIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkUpdateExist(ApiDebug apiDebug, ApiDebug originApiDebug) {
|
||||||
|
if (StringUtils.isBlank(apiDebug.getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ApiDebugExample example = new ApiDebugExample();
|
||||||
|
example.createCriteria()
|
||||||
|
.andIdNotEqualTo(apiDebug.getId())
|
||||||
|
.andModuleIdEqualTo(apiDebug.getModuleId() == null ? originApiDebug.getModuleId() : apiDebug.getModuleId())
|
||||||
|
.andNameEqualTo(apiDebug.getName());
|
||||||
|
if (CollectionUtils.isNotEmpty(apiDebugMapper.selectByExample(example))) {
|
||||||
|
throw new MSException(API_DEBUG_EXIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private ApiDebug checkResourceExist(String id) {
|
||||||
|
return ServiceUtils.checkResourceExist(apiDebugMapper.selectByPrimaryKey(id), "permission.system_api_debug.name");
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,12 +21,10 @@
|
||||||
"id": "PROJECT_API_DEBUG:READ+DELETE"
|
"id": "PROJECT_API_DEBUG:READ+DELETE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "PROJECT_API_DEBUG:READ+IMPORT",
|
"id": "PROJECT_API_DEBUG:READ+IMPORT"
|
||||||
"name": "permission.api_definition.import"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "PROJECT_API_DEBUG:READ+EXECUTE",
|
"id": "PROJECT_API_DEBUG:READ+EXECUTE"
|
||||||
"name": "permission.api_definition.execute"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -47,16 +45,13 @@
|
||||||
"id": "PROJECT_API_DEFINITION:READ+DELETE"
|
"id": "PROJECT_API_DEFINITION:READ+DELETE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "PROJECT_API_DEFINITION:READ+IMPORT",
|
"id": "PROJECT_API_DEFINITION:READ+IMPORT"
|
||||||
"name": "permission.api_definition.import"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "PROJECT_API_DEFINITION:READ+EXECUTE",
|
"id": "PROJECT_API_DEFINITION:READ+EXECUTE"
|
||||||
"name": "permission.api_definition.execute"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "PROJECT_API_DEFINITION:READ+EXPORT",
|
"id": "PROJECT_API_DEFINITION:READ+EXPORT"
|
||||||
"name": "permission.api_definition.export"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.controller.param.ApiDebugAddRequestDefinition;
|
||||||
|
import io.metersphere.api.controller.param.ApiDebugUpdateRequestDefinition;
|
||||||
|
import io.metersphere.api.domain.ApiDebug;
|
||||||
|
import io.metersphere.api.domain.ApiDebugBlob;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugAddRequest;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugDTO;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugSimpleDTO;
|
||||||
|
import io.metersphere.api.dto.debug.ApiDebugUpdateRequest;
|
||||||
|
import io.metersphere.api.mapper.ApiDebugBlobMapper;
|
||||||
|
import io.metersphere.api.mapper.ApiDebugMapper;
|
||||||
|
import io.metersphere.api.util.ApiDataUtils;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.MsHTTPElement;
|
||||||
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.system.base.BaseTest;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static io.metersphere.api.controller.result.ApiResultCode.API_DEBUG_EXIST;
|
||||||
|
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jianxing
|
||||||
|
* @date : 2023-11-7
|
||||||
|
*/
|
||||||
|
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public class ApiDebugControllerTests extends BaseTest {
|
||||||
|
private static final String BASE_PATH = "/api/debug/";
|
||||||
|
protected static final String DEFAULT_LIST = "list/{0}";
|
||||||
|
protected static final String HTTP_PROTOCOL = "HTTP";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApiDebugMapper apiDebugMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiDebugBlobMapper apiDebugBlobMapper;
|
||||||
|
private static ApiDebug addApiDebug;
|
||||||
|
private static ApiDebug anotherAddApiDebug;
|
||||||
|
@Override
|
||||||
|
protected String getBasePath() {
|
||||||
|
return BASE_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(0)
|
||||||
|
public void listEmpty() throws Exception {
|
||||||
|
// @@校验没有数据的情况
|
||||||
|
this.requestGetWithOk(DEFAULT_LIST, HTTP_PROTOCOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
public void add() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
ApiDebugAddRequest request = new ApiDebugAddRequest();
|
||||||
|
request.setPath("http://test.com");
|
||||||
|
request.setMethod("GET");
|
||||||
|
request.setName("test");
|
||||||
|
request.setProtocol(HTTP_PROTOCOL);
|
||||||
|
request.setModuleId("default");
|
||||||
|
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
|
||||||
|
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
|
||||||
|
MvcResult mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request);
|
||||||
|
// 校验请求成功数据
|
||||||
|
ApiDebug resultData = getResultData(mvcResult, ApiDebug.class);
|
||||||
|
this.addApiDebug = assertUpdateApiDebug(request, msHttpElement, resultData.getId());
|
||||||
|
|
||||||
|
// 再插入一条数据,便于修改时重名校验
|
||||||
|
request.setName("test1");
|
||||||
|
mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request);
|
||||||
|
resultData = getResultData(mvcResult, ApiDebug.class);
|
||||||
|
this.anotherAddApiDebug = assertUpdateApiDebug(request, msHttpElement, resultData.getId());
|
||||||
|
|
||||||
|
// @@重名校验异常
|
||||||
|
assertErrorCode(this.requestPost(DEFAULT_ADD, request), API_DEBUG_EXIST);
|
||||||
|
// 校验项目是否存在
|
||||||
|
request.setProjectId("111");
|
||||||
|
assertErrorCode(this.requestPost(DEFAULT_ADD, request), NOT_FOUND);
|
||||||
|
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(this.addApiDebug.getId(), OperationLogType.ADD);
|
||||||
|
// @@异常参数校验
|
||||||
|
createdGroupParamValidateTest(ApiDebugAddRequestDefinition.class, DEFAULT_ADD);
|
||||||
|
// @@校验权限
|
||||||
|
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_ADD, DEFAULT_ADD, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiDebug assertUpdateApiDebug(Object request, MsHTTPElement msHttpElement, String id) {
|
||||||
|
ApiDebug apiDebug = apiDebugMapper.selectByPrimaryKey(id);
|
||||||
|
ApiDebugBlob apiDebugBlob = apiDebugBlobMapper.selectByPrimaryKey(id);
|
||||||
|
ApiDebug copyApiDebug = BeanUtils.copyBean(new ApiDebug(), apiDebug);
|
||||||
|
copyApiDebug = BeanUtils.copyBean(copyApiDebug, request);
|
||||||
|
Assertions.assertEquals(apiDebug, copyApiDebug);
|
||||||
|
ApiDataUtils.setResolver(MsHTTPElement.class);
|
||||||
|
Assertions.assertEquals(msHttpElement, ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class));
|
||||||
|
return apiDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
public void update() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
ApiDebugUpdateRequest request = new ApiDebugUpdateRequest();
|
||||||
|
request.setId(addApiDebug.getId());
|
||||||
|
request.setPath("http://tesat.com");
|
||||||
|
request.setName("test1");
|
||||||
|
request.setMethod("POST");
|
||||||
|
request.setModuleId("default1");
|
||||||
|
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
|
||||||
|
msHttpElement.setName("test1");
|
||||||
|
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
|
||||||
|
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||||
|
// 校验请求成功数据
|
||||||
|
assertUpdateApiDebug(request, msHttpElement, request.getId());
|
||||||
|
|
||||||
|
// @@重名校验异常
|
||||||
|
request.setModuleId("default");
|
||||||
|
assertErrorCode(this.requestPost(DEFAULT_UPDATE, request), API_DEBUG_EXIST);
|
||||||
|
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(request.getId(), OperationLogType.UPDATE);
|
||||||
|
// @@异常参数校验
|
||||||
|
updatedGroupParamValidateTest(ApiDebugUpdateRequestDefinition.class, DEFAULT_UPDATE);
|
||||||
|
// @@校验权限
|
||||||
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_UPDATE, DEFAULT_UPDATE, request);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void list() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
MvcResult mvcResult = this.requestGetWithOk(DEFAULT_LIST, HTTP_PROTOCOL)
|
||||||
|
.andReturn();
|
||||||
|
// 校验数据是否正确
|
||||||
|
List<ApiDebugSimpleDTO> apiDebugList = getResultDataArray(mvcResult, ApiDebugSimpleDTO.class);
|
||||||
|
Assertions.assertEquals(apiDebugList.size(), 2);
|
||||||
|
Assertions.assertEquals(apiDebugList.get(0), BeanUtils.copyBean(new ApiDebugSimpleDTO(),
|
||||||
|
apiDebugMapper.selectByPrimaryKey(addApiDebug.getId())));
|
||||||
|
Assertions.assertEquals(apiDebugList.get(1),
|
||||||
|
BeanUtils.copyBean(new ApiDebugSimpleDTO(), apiDebugMapper.selectByPrimaryKey(anotherAddApiDebug.getId())));
|
||||||
|
|
||||||
|
// @@校验权限
|
||||||
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ, DEFAULT_LIST, HTTP_PROTOCOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
public void get() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
MvcResult mvcResult = this.requestGetWithOk(DEFAULT_GET, addApiDebug.getId())
|
||||||
|
.andReturn();
|
||||||
|
ApiDataUtils.setResolver(MsHTTPElement.class);
|
||||||
|
ApiDebugDTO apiDebugDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult).get("data")), ApiDebugDTO.class);
|
||||||
|
// 校验数据是否正确
|
||||||
|
ApiDebugDTO copyApiDebugDTO = BeanUtils.copyBean(new ApiDebugDTO(), apiDebugMapper.selectByPrimaryKey(addApiDebug.getId()));
|
||||||
|
ApiDebugBlob apiDebugBlob = apiDebugBlobMapper.selectByPrimaryKey(addApiDebug.getId());
|
||||||
|
copyApiDebugDTO.setRequest(ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class));
|
||||||
|
Assertions.assertEquals(apiDebugDTO, copyApiDebugDTO);
|
||||||
|
// @@校验权限
|
||||||
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ, DEFAULT_GET, apiDebugDTO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
public void delete() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
this.requestGetWithOk(DEFAULT_DELETE, addApiDebug.getId());
|
||||||
|
// 校验请求成功数据
|
||||||
|
Assertions.assertNull(apiDebugMapper.selectByPrimaryKey(addApiDebug.getId()));
|
||||||
|
Assertions.assertNull(apiDebugBlobMapper.selectByPrimaryKey(addApiDebug.getId()));
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(addApiDebug.getId(), OperationLogType.DELETE);
|
||||||
|
// @@校验权限
|
||||||
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_DELETE, DEFAULT_DELETE, addApiDebug.getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -273,7 +273,7 @@ public class ApiDebugModuleControllerTests extends BaseTest {
|
||||||
request = new ModuleCreateRequest();
|
request = new ModuleCreateRequest();
|
||||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
request.setName("defaultProject");
|
request.setName("defaultProject");
|
||||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ_ADD, URL_MODULE_ADD, request);
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_ADD, URL_MODULE_ADD, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -365,7 +365,7 @@ public class ApiDebugModuleControllerTests extends BaseTest {
|
||||||
updateRequest = new ModuleUpdateRequest();
|
updateRequest = new ModuleUpdateRequest();
|
||||||
updateRequest.setId(apiDebugModules.get(0).getId());
|
updateRequest.setId(apiDebugModules.get(0).getId());
|
||||||
updateRequest.setName("default-update-Project");
|
updateRequest.setName("default-update-Project");
|
||||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ_UPDATE, URL_MODULE_UPDATE, updateRequest);
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_UPDATE, URL_MODULE_UPDATE, updateRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -638,7 +638,7 @@ public class ApiDebugModuleControllerTests extends BaseTest {
|
||||||
|
|
||||||
checkLog(a1Node.getId(), OperationLogType.UPDATE, URL_MODULE_MOVE);
|
checkLog(a1Node.getId(), OperationLogType.UPDATE, URL_MODULE_MOVE);
|
||||||
checkLog(a3Node.getId(), OperationLogType.UPDATE, URL_MODULE_MOVE);
|
checkLog(a3Node.getId(), OperationLogType.UPDATE, URL_MODULE_MOVE);
|
||||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ_UPDATE, URL_MODULE_MOVE, request);
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_UPDATE, URL_MODULE_MOVE, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -750,7 +750,7 @@ public class ApiDebugModuleControllerTests extends BaseTest {
|
||||||
//service层判断:测试删除空集合
|
//service层判断:测试删除空集合
|
||||||
apiDebugModuleService.deleteModule(new ArrayList<>(), "admin", DEFAULT_PROJECT_ID);
|
apiDebugModuleService.deleteModule(new ArrayList<>(), "admin", DEFAULT_PROJECT_ID);
|
||||||
//校验权限
|
//校验权限
|
||||||
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ_DELETE, String.format(URL_MODULE_DELETE, IDGenerator.nextNum()));
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_DELETE, String.format(URL_MODULE_DELETE, IDGenerator.nextNum()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.util.ApiDataUtils;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.*;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.auth.BasicAuth;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.auth.DigestAuth;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.auth.HTTPAuth;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.auth.NoAuth;
|
||||||
|
import io.metersphere.sdk.dto.api.request.http.body.*;
|
||||||
|
import io.metersphere.sdk.dto.api.request.processors.SQLProcessor;
|
||||||
|
import io.metersphere.sdk.dto.api.request.processors.ScriptProcessor;
|
||||||
|
import io.metersphere.sdk.dto.api.request.processors.TimeWaitingProcessor;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 11:17
|
||||||
|
*/
|
||||||
|
public class MsHTTPElementTest {
|
||||||
|
public MsHTTPElementTest() {
|
||||||
|
ApiDataUtils.setResolver(MsHTTPElement.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bodyTest() {
|
||||||
|
|
||||||
|
MsHTTPElement msHTTPElement = getMsHttpElement();
|
||||||
|
|
||||||
|
List bodies = new ArrayList<>();
|
||||||
|
|
||||||
|
FormDataBody formDataBody = new FormDataBody();
|
||||||
|
FormDataKV formDataKV = new FormDataKV();
|
||||||
|
formDataKV.setEnable(false);
|
||||||
|
formDataKV.setContentType("text/plain");
|
||||||
|
formDataKV.setEncode(true);
|
||||||
|
formDataKV.setMaxLength(10);
|
||||||
|
formDataKV.setMinLength(8);
|
||||||
|
formDataKV.setParamType("text");
|
||||||
|
formDataKV.setDescription("test");
|
||||||
|
formDataKV.setRequired(true);
|
||||||
|
formDataKV.setValue("value");
|
||||||
|
formDataKV.setKey("key");
|
||||||
|
formDataBody.setFromValues(List.of(formDataKV));
|
||||||
|
bodies.add(formDataBody);
|
||||||
|
|
||||||
|
WWWFormBody wwwFormBody = new WWWFormBody();
|
||||||
|
wwwFormBody.setFromValues(List.of(formDataKV));
|
||||||
|
bodies.add(wwwFormBody);
|
||||||
|
|
||||||
|
JsonBody jsonBody = new JsonBody();
|
||||||
|
jsonBody.setValue("{}");
|
||||||
|
bodies.add(jsonBody);
|
||||||
|
|
||||||
|
bodies.add(new NoneBody());
|
||||||
|
|
||||||
|
RawBody rawBody = new RawBody();
|
||||||
|
rawBody.setValue("A");
|
||||||
|
bodies.add(rawBody);
|
||||||
|
|
||||||
|
XmlBody xmlBody = new XmlBody();
|
||||||
|
xmlBody.setValue("<a/>");
|
||||||
|
bodies.add(xmlBody);
|
||||||
|
|
||||||
|
BinaryBody binaryBody = new BinaryBody();
|
||||||
|
binaryBody.setFilePath("/test/a.png");
|
||||||
|
binaryBody.setFileName("a.png");
|
||||||
|
bodies.add(binaryBody);
|
||||||
|
|
||||||
|
|
||||||
|
for (Object body : bodies) {
|
||||||
|
msHTTPElement.setBody((Body) body);
|
||||||
|
String json = ApiDataUtils.toJSONString(msHTTPElement);
|
||||||
|
Assertions.assertNotNull(json);
|
||||||
|
Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void authConfigTest() {
|
||||||
|
|
||||||
|
MsHTTPElement msHTTPElement = getMsHttpElement();
|
||||||
|
|
||||||
|
List authConfigs = new ArrayList<>();
|
||||||
|
|
||||||
|
authConfigs.add(new NoAuth());
|
||||||
|
|
||||||
|
BasicAuth basicAuth = new BasicAuth();
|
||||||
|
basicAuth.setUserName("test");
|
||||||
|
basicAuth.setPassword("passwd");
|
||||||
|
authConfigs.add(basicAuth);
|
||||||
|
|
||||||
|
DigestAuth digestAuth = new DigestAuth();
|
||||||
|
digestAuth.setUserName("test");
|
||||||
|
digestAuth.setPassword("passwd");
|
||||||
|
authConfigs.add(digestAuth);
|
||||||
|
|
||||||
|
for (Object authConfig : authConfigs) {
|
||||||
|
msHTTPElement.setAuthConfig((HTTPAuth) authConfig);
|
||||||
|
String json = ApiDataUtils.toJSONString(msHTTPElement);
|
||||||
|
Assertions.assertNotNull(json);
|
||||||
|
Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void msProcessorTest() {
|
||||||
|
|
||||||
|
MsHTTPElement msHTTPElement = getMsHttpElement();
|
||||||
|
|
||||||
|
List processors = new ArrayList<>();
|
||||||
|
|
||||||
|
ScriptProcessor scriptProcessor = new ScriptProcessor();
|
||||||
|
scriptProcessor.setEnable(true);
|
||||||
|
scriptProcessor.setScript("script");
|
||||||
|
scriptProcessor.setScriptLanguage("js");
|
||||||
|
scriptProcessor.setJsrEnable(true);
|
||||||
|
processors.add(scriptProcessor);
|
||||||
|
|
||||||
|
SQLProcessor sqlProcessor = new SQLProcessor();
|
||||||
|
sqlProcessor.setScript("script");
|
||||||
|
sqlProcessor.setEnable(true);
|
||||||
|
sqlProcessor.setDataSourceId("dataSourceId");
|
||||||
|
KeyValueParam keyValueParam = new KeyValueParam();
|
||||||
|
keyValueParam.setKey("key");
|
||||||
|
keyValueParam.setValue("value");
|
||||||
|
sqlProcessor.setVariables(List.of(keyValueParam));
|
||||||
|
sqlProcessor.setResultVariable("ddd");
|
||||||
|
sqlProcessor.setQueryTimeout(1111);
|
||||||
|
sqlProcessor.setVariableNames("test");
|
||||||
|
processors.add(sqlProcessor);
|
||||||
|
|
||||||
|
TimeWaitingProcessor timeWaitingProcessor = new TimeWaitingProcessor();
|
||||||
|
timeWaitingProcessor.setDelay(1000);
|
||||||
|
timeWaitingProcessor.setEnable(true);
|
||||||
|
processors.add(timeWaitingProcessor);
|
||||||
|
|
||||||
|
msHTTPElement.setPreProcessors(processors);
|
||||||
|
msHTTPElement.setPostProcessors(processors);
|
||||||
|
String json = ApiDataUtils.toJSONString(msHTTPElement);
|
||||||
|
Assertions.assertNotNull(json);
|
||||||
|
Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MsHTTPElement getMsHttpElement() {
|
||||||
|
MsHTTPElement msHTTPElement = new MsHTTPElement();
|
||||||
|
msHTTPElement.setUrl("http://www.test.com");
|
||||||
|
msHTTPElement.setPath("/test");
|
||||||
|
msHTTPElement.setMethod("GET");
|
||||||
|
msHTTPElement.setName("name");
|
||||||
|
msHTTPElement.setEnable(false);
|
||||||
|
|
||||||
|
Header header = new Header();
|
||||||
|
header.setEnable(false);
|
||||||
|
header.setValue("value");
|
||||||
|
header.setKey("key");
|
||||||
|
header.setDescription("desc");
|
||||||
|
msHTTPElement.setHeaders(List.of(header));
|
||||||
|
|
||||||
|
RestParam restParam = new RestParam();
|
||||||
|
restParam.setKey("key");
|
||||||
|
restParam.setValue("value");
|
||||||
|
restParam.setEnable(false);
|
||||||
|
restParam.setDescription("desc");
|
||||||
|
restParam.setRequired(true);
|
||||||
|
msHTTPElement.setRest(List.of(restParam));
|
||||||
|
|
||||||
|
QueryParam queryParam = new QueryParam();
|
||||||
|
queryParam.setKey("key");
|
||||||
|
queryParam.setValue("value");
|
||||||
|
queryParam.setEnable(false);
|
||||||
|
queryParam.setDescription("desc");
|
||||||
|
queryParam.setRequired(true);
|
||||||
|
msHTTPElement.setQuery(List.of(queryParam));
|
||||||
|
|
||||||
|
MsHTTPConfig msHTTPConfig = new MsHTTPConfig();
|
||||||
|
msHTTPConfig.setFollowRedirects(true);
|
||||||
|
msHTTPConfig.setAutoRedirects(true);
|
||||||
|
msHTTPConfig.setResponseTimeout(1000L);
|
||||||
|
msHTTPConfig.setConnectTimeout(1000L);
|
||||||
|
msHTTPConfig.setCertificateAlias("alias");
|
||||||
|
msHTTPElement.setOtherConfig(msHTTPConfig);
|
||||||
|
|
||||||
|
return msHTTPElement;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package io.metersphere.api.controller.param;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 14:49
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ApiDebugAddRequestDefinition {
|
||||||
|
|
||||||
|
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.name.not_blank}")
|
||||||
|
@Size(min = 1, max = 255, message = "{api_debug.name.length_range}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "接口协议", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.protocol.not_blank}")
|
||||||
|
@Size(min = 1, max = 20, message = "{api_debug.protocol.length_range}")
|
||||||
|
private String protocol;
|
||||||
|
|
||||||
|
@Schema(description = "http协议类型post/get/其它协议则是协议名(mqtt)")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
@Schema(description = "http协议路径/其它协议则为空")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@Schema(description = "项目fk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.project_id.not_blank}")
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.project_id.length_range}")
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "模块fk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.module_id.not_blank}")
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.module_id.length_range}")
|
||||||
|
private String moduleId;
|
||||||
|
|
||||||
|
@Schema(description = "请求内容")
|
||||||
|
@NotBlank
|
||||||
|
private String request;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package io.metersphere.api.controller.param;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 14:33
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ApiDebugUpdateRequestDefinition {
|
||||||
|
|
||||||
|
@Schema(description = "接口pk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.id.not_blank}")
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.id.length_range}")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.name.not_blank}")
|
||||||
|
@Size(min = 1, max = 255, message = "{api_debug.name.length_range}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "http协议类型post/get/其它协议则是协议名(mqtt)")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
@Schema(description = "http协议路径/其它协议则为空")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@Schema(description = "模块fk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_debug.module_id.not_blank}")
|
||||||
|
@Size(min = 1, max = 50, message = "{api_debug.module_id.length_range}")
|
||||||
|
private String moduleId;
|
||||||
|
|
||||||
|
@Schema(description = "请求内容")
|
||||||
|
@NotBlank
|
||||||
|
private String request;
|
||||||
|
}
|
|
@ -1,10 +1,6 @@
|
||||||
package io.metersphere.project.controller;
|
package io.metersphere.project.controller;
|
||||||
|
|
||||||
import io.metersphere.sdk.constants.*;
|
import io.metersphere.sdk.constants.*;
|
||||||
import io.metersphere.system.dto.sdk.request.StatusDefinitionUpdateRequest;
|
|
||||||
import io.metersphere.system.dto.sdk.request.StatusFlowUpdateRequest;
|
|
||||||
import io.metersphere.system.dto.sdk.request.StatusItemAddRequest;
|
|
||||||
import io.metersphere.system.dto.sdk.request.StatusItemUpdateRequest;
|
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
import io.metersphere.system.base.BaseTest;
|
import io.metersphere.system.base.BaseTest;
|
||||||
import io.metersphere.system.controller.OrganizationStatusFlowSettingControllerTest;
|
import io.metersphere.system.controller.OrganizationStatusFlowSettingControllerTest;
|
||||||
|
@ -12,8 +8,13 @@ import io.metersphere.system.controller.param.StatusDefinitionUpdateRequestDefin
|
||||||
import io.metersphere.system.controller.param.StatusFlowUpdateRequestDefinition;
|
import io.metersphere.system.controller.param.StatusFlowUpdateRequestDefinition;
|
||||||
import io.metersphere.system.controller.param.StatusItemAddRequestDefinition;
|
import io.metersphere.system.controller.param.StatusItemAddRequestDefinition;
|
||||||
import io.metersphere.system.controller.param.StatusItemUpdateRequestDefinition;
|
import io.metersphere.system.controller.param.StatusItemUpdateRequestDefinition;
|
||||||
import io.metersphere.system.domain.*;
|
import io.metersphere.system.domain.OrganizationParameter;
|
||||||
|
import io.metersphere.system.domain.StatusItem;
|
||||||
import io.metersphere.system.dto.StatusItemDTO;
|
import io.metersphere.system.dto.StatusItemDTO;
|
||||||
|
import io.metersphere.system.dto.sdk.request.StatusDefinitionUpdateRequest;
|
||||||
|
import io.metersphere.system.dto.sdk.request.StatusFlowUpdateRequest;
|
||||||
|
import io.metersphere.system.dto.sdk.request.StatusItemAddRequest;
|
||||||
|
import io.metersphere.system.dto.sdk.request.StatusItemUpdateRequest;
|
||||||
import io.metersphere.system.log.constants.OperationLogType;
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
import io.metersphere.system.mapper.OrganizationParameterMapper;
|
import io.metersphere.system.mapper.OrganizationParameterMapper;
|
||||||
import io.metersphere.system.mapper.StatusItemMapper;
|
import io.metersphere.system.mapper.StatusItemMapper;
|
||||||
|
@ -23,7 +24,6 @@ import io.metersphere.system.service.BaseStatusItemService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.metersphere.system.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-11-07 18:43
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ProtocolDTO {
|
||||||
|
private String protocol;
|
||||||
|
private String name;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package io.metersphere.system.service;
|
||||||
|
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractProtocolPlugin;
|
||||||
|
import io.metersphere.sdk.constants.PluginScenarioType;
|
||||||
|
import io.metersphere.system.domain.Plugin;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.pf4j.PluginWrapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class ApiPluginService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PluginLoadService pluginLoadService;
|
||||||
|
@Resource
|
||||||
|
private BasePluginService basePluginService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取协议插件的的协议列表
|
||||||
|
* @param orgId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> getProtocols(String orgId) {
|
||||||
|
// 查询组织下有权限的插件
|
||||||
|
Set<String> pluginIds = basePluginService.getOrgEnabledPlugins(orgId, PluginScenarioType.API_PROTOCOL)
|
||||||
|
.stream()
|
||||||
|
.map(Plugin::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
List<PluginWrapper> plugins = pluginLoadService.getMsPluginManager().getPlugins();
|
||||||
|
return plugins.stream()
|
||||||
|
.filter(plugin -> pluginIds.contains(plugin.getPluginId()) && plugin.getPlugin() instanceof AbstractProtocolPlugin)
|
||||||
|
.map(plugin -> ((AbstractProtocolPlugin) plugin.getPlugin()).getProtocol())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
|
@ -119,6 +119,7 @@ public class BaseUserRoleService {
|
||||||
put("READ+IMPORT", "permission.import");
|
put("READ+IMPORT", "permission.import");
|
||||||
put("READ+RECOVER", "permission.recover");
|
put("READ+RECOVER", "permission.recover");
|
||||||
put("READ+EXPORT", "permission.export");
|
put("READ+EXPORT", "permission.export");
|
||||||
|
put("READ+EXECUTE", "permission.execute");
|
||||||
}};
|
}};
|
||||||
return Translator.get(translationMap.get(permissionKey));
|
return Translator.get(translationMap.get(permissionKey));
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,7 +264,7 @@ public abstract class BaseTest {
|
||||||
return JSON.parseArray(JSON.toJSONString(data), clazz);
|
return JSON.parseArray(JSON.toJSONString(data), clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map parseResponse(MvcResult mvcResult) throws UnsupportedEncodingException {
|
protected static Map parseResponse(MvcResult mvcResult) throws UnsupportedEncodingException {
|
||||||
return JSON.parseMap(mvcResult.getResponse().getContentAsString(Charset.defaultCharset()));
|
return JSON.parseMap(mvcResult.getResponse().getContentAsString(Charset.defaultCharset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue