feat(接口测试): 处理body参数的jmx转换
--task=1013377 --user=陈建星 接口测试-接口调试-后台调试执行 https://www.tapd.cn/55049933/s/1447114
This commit is contained in:
parent
a587b7bcb5
commit
b55ba39b58
|
@ -50,7 +50,7 @@ public class DefaultRepositoryDir {
|
|||
private static final String PROJECT_FILE_MANAGEMENT_PREVIEW_DIR = PROJECT_DIR + "/file-management/preview";
|
||||
/**
|
||||
* 接口调试相关文件的存储目录
|
||||
* project/{projectId}/apiCase/{apiDebugId}
|
||||
* project/{projectId}/api-debug/{apiDebugId}
|
||||
*/
|
||||
private static final String PROJECT_API_DEBUG_DIR = PROJECT_DIR + "/api-debug/%s";
|
||||
private static final String PROJECT_BUG_DIR = PROJECT_DIR + "/bug/%s";
|
||||
|
|
|
@ -29,14 +29,29 @@ public class LocalRepositoryDir {
|
|||
* 插件存储目录
|
||||
*/
|
||||
private static final String SYSTEM_PLUGIN_DIR = SYSTEM_ROOT_DIR + "/plugin";
|
||||
private static final String SYSTEM_BODY_ENVIRONMENT_TEM_DIR = SYSTEM_ROOT_DIR + "/body/environment/tmp";
|
||||
/**
|
||||
* 系统临时文件的存放目录
|
||||
* system/temp
|
||||
* 会定时清理
|
||||
*/
|
||||
private static final String SYSTEM_TEMP_DIR = SYSTEM_ROOT_DIR + "/temp";
|
||||
/**
|
||||
* 系统缓存文件存放目录
|
||||
* 目前仅执行机缓存执行文件使用到
|
||||
* system/cache
|
||||
*/
|
||||
private static final String SYSTEM_CACHE_DIR = SYSTEM_ROOT_DIR + "/cache";
|
||||
/*------ end: 系统下资源目录 --------*/
|
||||
|
||||
public static String getPluginDir() {
|
||||
return SYSTEM_PLUGIN_DIR;
|
||||
}
|
||||
|
||||
public static String getBodyEnvironmentTmpDir() {
|
||||
return SYSTEM_BODY_ENVIRONMENT_TEM_DIR;
|
||||
public static String getSystemTempDir() {
|
||||
return SYSTEM_TEMP_DIR;
|
||||
}
|
||||
|
||||
public static String getSystemCacheDir() {
|
||||
return SYSTEM_CACHE_DIR;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
package io.metersphere.sdk.constants;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum StorageType {
|
||||
MINIO, GIT, LOCAL
|
||||
|
||||
MINIO, GIT, LOCAL;
|
||||
|
||||
public static boolean isGit(String storage) {
|
||||
return StringUtils.equalsIgnoreCase(GIT.name(), storage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package io.metersphere.sdk.dto.api.task;
|
||||
|
||||
import io.metersphere.sdk.dto.FileMetadataRepositoryDTO;
|
||||
import io.metersphere.sdk.dto.FileModuleRepositoryDTO;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-15 16:59
|
||||
*/
|
||||
@Data
|
||||
public class ApiExecuteFileInfo {
|
||||
private String fileId;
|
||||
private String fileName;
|
||||
/**
|
||||
* 文件存储方式
|
||||
*/
|
||||
private String storage;
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
private String projectId;
|
||||
/**
|
||||
* 资源ID
|
||||
*/
|
||||
private String resourceId;
|
||||
|
||||
/**
|
||||
* git文件的版本信息
|
||||
*/
|
||||
private FileMetadataRepositoryDTO fileMetadataRepositoryDTO;
|
||||
/**
|
||||
* 文件的仓库信息
|
||||
*/
|
||||
private FileModuleRepositoryDTO fileModuleRepositoryDTO;
|
||||
}
|
|
@ -28,19 +28,28 @@ public class TaskRequest implements Serializable {
|
|||
* 执行的资源ID
|
||||
*/
|
||||
private String testId;
|
||||
/**
|
||||
* 点击调试时,尚未保存的文件ID列表
|
||||
*/
|
||||
private List<String> tempFileIds;
|
||||
/**
|
||||
* 执行模式
|
||||
*/
|
||||
private String runMode;
|
||||
/**
|
||||
* 资源类型
|
||||
* ApiResourceType
|
||||
*/
|
||||
private String resourceType;
|
||||
|
||||
|
||||
/**
|
||||
* 点击调试时,尚未保存的本地上传的文件列表
|
||||
*/
|
||||
private List<ApiExecuteFileInfo> localTempFiles;
|
||||
/**
|
||||
* 通过本地上传的文件ID列表
|
||||
*/
|
||||
private List<ApiExecuteFileInfo> localFiles;
|
||||
/**
|
||||
* 关联文件管理的文件列表
|
||||
* 这里记录文件名,mino存的文件名是id
|
||||
* 执行时下载文件后,按原文件命名
|
||||
*/
|
||||
private List<ApiExecuteFileInfo> refFiles;
|
||||
// TODO 其它执行参数
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package io.metersphere.api.dto.debug;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
public class ApiDebugRunRequest {
|
||||
@Schema(description = "接口ID")
|
||||
@NotNull
|
||||
private String id;
|
||||
@Schema(description = "环境ID")
|
||||
private String environmentId;
|
||||
|
||||
@Schema(description = "点击调试时尚未保存的文件ID列表")
|
||||
private List<String> tempFileIds;
|
||||
|
||||
@NotNull
|
||||
@Schema(description = "请求内容")
|
||||
private String request;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
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;
|
||||
|
@ -20,13 +18,12 @@ 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})
|
||||
@NotBlank(message = "{api_debug.id.not_blank}")
|
||||
@Size(max = 50, message = "{api_debug.id.length_range}")
|
||||
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})
|
||||
@Size(max = 255, message = "{api_debug.name.length_range}")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "http协议类型post/get/其它协议则是协议名(mqtt)")
|
||||
|
@ -36,12 +33,10 @@ public class ApiDebugUpdateRequest implements Serializable {
|
|||
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})
|
||||
@Size(max = 50, message = "{api_debug.module_id.length_range}")
|
||||
private String moduleId;
|
||||
|
||||
@Schema(description = "请求内容")
|
||||
@NotBlank
|
||||
private String request;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.metersphere.api.dto.debug;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -8,9 +7,21 @@ import java.util.List;
|
|||
@Data
|
||||
public class ApiResourceRunRequest {
|
||||
private String id;
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
private String projectId;
|
||||
/**
|
||||
* 资源ID
|
||||
*/
|
||||
private String testId;
|
||||
/**
|
||||
* 测试报告ID
|
||||
*/
|
||||
private String reportId;
|
||||
/**
|
||||
* 环境ID
|
||||
*/
|
||||
private String environmentId;
|
||||
/**
|
||||
* 执行模式
|
||||
|
@ -18,9 +29,15 @@ public class ApiResourceRunRequest {
|
|||
private String runMode;
|
||||
/**
|
||||
* 资源类型
|
||||
* @see io.metersphere.api.constants.ApiResourceType
|
||||
*/
|
||||
private String resourceType;
|
||||
@Schema(description = "点击调试时尚未保存的文件ID列表")
|
||||
private List<String> tempFileIds;
|
||||
/**
|
||||
* 请求内容
|
||||
*/
|
||||
private String request;
|
||||
/**
|
||||
* 点击调试时尚未保存的文件列表
|
||||
*/
|
||||
private List<String> tempFileIds;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.api.dto.request.http;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
|
@ -8,6 +9,10 @@ import lombok.Data;
|
|||
*/
|
||||
@Data
|
||||
public class KeyValueParam {
|
||||
/**
|
||||
* 参数ID
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 键
|
||||
*/
|
||||
|
@ -16,4 +21,8 @@ public class KeyValueParam {
|
|||
* 值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
public boolean isValid() {
|
||||
return StringUtils.isNotBlank(key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import lombok.Data;
|
|||
*/
|
||||
@Data
|
||||
public class BinaryBody {
|
||||
private String fileId;
|
||||
private String fileName;
|
||||
private BodyFile bodyFile;
|
||||
private String description;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@ package io.metersphere.api.dto.request.http.body;
|
|||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-11-06 16:59
|
||||
|
@ -22,6 +25,35 @@ public class Body {
|
|||
private RawBody rawBody;
|
||||
private BinaryBody binaryBody;
|
||||
|
||||
private static Map<BodyType, Class> bodyTypeClassMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
bodyTypeClassMap.put(BodyType.NONE, NoneBody.class);
|
||||
bodyTypeClassMap.put(BodyType.FORM_DATA, FormDataBody.class);
|
||||
bodyTypeClassMap.put(BodyType.WWW_FORM, WWWFormBody.class);
|
||||
bodyTypeClassMap.put(BodyType.JSON, JsonBody.class);
|
||||
bodyTypeClassMap.put(BodyType.XML, XmlBody.class);
|
||||
bodyTypeClassMap.put(BodyType.RAW, RawBody.class);
|
||||
bodyTypeClassMap.put(BodyType.BINARY, BinaryBody.class);
|
||||
}
|
||||
|
||||
public Class getBodyClassByType() {
|
||||
return bodyTypeClassMap.get(BodyType.valueOf(bodyType));
|
||||
}
|
||||
|
||||
public Object getBodyDataByType() {
|
||||
Map<BodyType, Object> boadyDataMap = new HashMap<>();
|
||||
boadyDataMap.put(BodyType.NONE, noneBody);
|
||||
boadyDataMap.put(BodyType.FORM_DATA, formDataBody);
|
||||
boadyDataMap.put(BodyType.WWW_FORM, wwwFormBody);
|
||||
boadyDataMap.put(BodyType.JSON, jsonBody);
|
||||
boadyDataMap.put(BodyType.XML, xmlBody);
|
||||
boadyDataMap.put(BodyType.RAW, rawBody);
|
||||
boadyDataMap.put(BodyType.BINARY, binaryBody);
|
||||
return boadyDataMap.get(BodyType.valueOf(bodyType));
|
||||
}
|
||||
|
||||
|
||||
public enum BodyType {
|
||||
BINARY,
|
||||
FORM_DATA,
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.api.dto.request.http.body;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BodyFile {
|
||||
/**
|
||||
* 记录文件的ID,防止重名
|
||||
* 生成脚本时,通过 fileId + value(文件名) 获取文件路径
|
||||
*/
|
||||
private String fileId;
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private String fileName;
|
||||
}
|
|
@ -1,28 +1,20 @@
|
|||
package io.metersphere.api.dto.request.http.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.KeyValueEnableParam;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-11-06 18:11
|
||||
*/
|
||||
@Data
|
||||
public class FormDataKV extends KeyValueEnableParam {
|
||||
private String paramType;
|
||||
private Boolean required = false;
|
||||
private Integer minLength;
|
||||
private Integer maxLength;
|
||||
private String contentType;
|
||||
private Boolean encode = false;
|
||||
/**
|
||||
* 记录文件的ID,防止重名
|
||||
* 生成脚本时,通过 fileId + value(文件名) 获取文件路径
|
||||
*/
|
||||
private String fileId;
|
||||
/**
|
||||
* 文件存储方式
|
||||
* 对象存储和引用(FILE_REF)
|
||||
*/
|
||||
private String storage;
|
||||
public class FormDataKV extends WWWFormKV {
|
||||
|
||||
private List<BodyFile> files;
|
||||
|
||||
public boolean isFile() {
|
||||
return StringUtils.equalsIgnoreCase(getParamType(), WWWFormParamType.FILE.name());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public class JsonBody {
|
|||
/**
|
||||
* 是否启用 json-schema
|
||||
*/
|
||||
private Boolean enableJsonSchema;
|
||||
private Boolean enableJsonSchema = false;
|
||||
/**
|
||||
* 没有启用 json-schema 时的 json 参数值
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package io.metersphere.api.dto.request.http.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.KeyValueEnableParam;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-11-06 18:11
|
||||
*/
|
||||
@Data
|
||||
public class WWWFormKV extends KeyValueEnableParam {
|
||||
/**
|
||||
* 参数类型
|
||||
*
|
||||
* @see WWWFormParamType
|
||||
*/
|
||||
private String paramType;
|
||||
private Boolean required = false;
|
||||
private Integer minLength;
|
||||
private Integer maxLength;
|
||||
private String contentType;
|
||||
private Boolean encode = false;
|
||||
|
||||
enum WWWFormParamType {
|
||||
/**
|
||||
* 默认 application/text
|
||||
*/
|
||||
STRING, INTEGER, NUMBER, ARRAY,
|
||||
/**
|
||||
* 默认 application/octet-stream
|
||||
*/
|
||||
FILE,
|
||||
/**
|
||||
* 默认 application/json
|
||||
*/
|
||||
JSON
|
||||
}
|
||||
}
|
|
@ -28,7 +28,6 @@ public class JmeterTestElementParser implements TestElementParser {
|
|||
|
||||
private Boolean onSampleError;
|
||||
private String name;
|
||||
private Boolean enable = true;
|
||||
private ParameterConfig config;
|
||||
private boolean displayJMeterProperties = false;
|
||||
|
||||
|
@ -36,13 +35,18 @@ public class JmeterTestElementParser implements TestElementParser {
|
|||
|
||||
private boolean displaySystemProperties = false;
|
||||
|
||||
/**
|
||||
* 解析生成 jmx 脚本
|
||||
* @param msTestElement
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String parse(AbstractMsTestElement msTestElement, ParameterConfig config) {
|
||||
this.config = config;
|
||||
HashTree hashTree = new ListedHashTree();
|
||||
TestPlan testPlan = getPlan();
|
||||
name = msTestElement.getName();
|
||||
enable = msTestElement.getEnable();
|
||||
final HashTree testPlanTree = hashTree.add(testPlan);
|
||||
final HashTree groupTree = testPlanTree.add(getThreadGroup());
|
||||
// 添加 debugSampler
|
||||
|
@ -82,11 +86,11 @@ public class JmeterTestElementParser implements TestElementParser {
|
|||
loopController.setName("LoopController");
|
||||
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
|
||||
loopController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("LoopControlPanel"));
|
||||
loopController.setEnabled(this.enable);
|
||||
loopController.setEnabled(true);
|
||||
loopController.setLoops(1);
|
||||
|
||||
ThreadGroup threadGroup = new ThreadGroup();
|
||||
threadGroup.setEnabled(this.enable);
|
||||
threadGroup.setEnabled(true);
|
||||
threadGroup.setName(config.getReportId());
|
||||
threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
|
||||
threadGroup.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ThreadGroupGui"));
|
||||
|
|
|
@ -2,31 +2,68 @@ package io.metersphere.api.parser.jmeter;
|
|||
|
||||
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
|
||||
import io.metersphere.api.dto.request.http.body.Body;
|
||||
import io.metersphere.api.parser.jmeter.body.MsBodyConverter;
|
||||
import io.metersphere.api.parser.jmeter.body.MsBodyConverterFactory;
|
||||
import io.metersphere.api.parser.jmeter.body.MsFormDataBodyConverter;
|
||||
import io.metersphere.api.parser.jmeter.body.MsWWWFormBodyConverter;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-10-27 10:07
|
||||
*
|
||||
* <p>
|
||||
* 脚本解析器
|
||||
*/
|
||||
public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTTPElement> {
|
||||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, MsHTTPElement msHTTPElement, ParameterConfig msParameter) {
|
||||
ParameterConfig config = msParameter;
|
||||
private ParameterConfig config;
|
||||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, MsHTTPElement msHTTPElement, ParameterConfig config) {
|
||||
this.config = config;
|
||||
HTTPSamplerProxy sampler = new HTTPSamplerProxy();
|
||||
sampler.setName(msHTTPElement.getName());
|
||||
sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
|
||||
sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("HttpTestSampleGui"));
|
||||
|
||||
sampler.setMethod(msHTTPElement.getMethod());
|
||||
// todo 根据环境设置
|
||||
sampler.setDomain(msHTTPElement.getUrl());
|
||||
sampler.setPath(msHTTPElement.getPath());
|
||||
|
||||
handleBody(sampler, msHTTPElement);
|
||||
HashTree httpTree = tree.add(sampler);
|
||||
parseChild(httpTree, msHTTPElement, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析body参数
|
||||
*
|
||||
* @param sampler
|
||||
* @param msHTTPElement
|
||||
*/
|
||||
private void handleBody(HTTPSamplerProxy sampler, MsHTTPElement msHTTPElement) {
|
||||
Body body = msHTTPElement.getBody();
|
||||
// 请求体处理
|
||||
if (body != null) {
|
||||
Class bodyClass = body.getBodyClassByType();
|
||||
MsBodyConverter converter = MsBodyConverterFactory.getConverter(bodyClass);
|
||||
|
||||
// 这里get请求,不处理 form-date 和 www-form-urlencoded 类型的参数
|
||||
// 否则会被 jmeter 作为 query 参数
|
||||
if (StringUtils.equalsIgnoreCase(msHTTPElement.getMethod(), HttpMethod.GET.name())
|
||||
&& (converter instanceof MsWWWFormBodyConverter || converter instanceof MsFormDataBodyConverter)) {
|
||||
return;
|
||||
}
|
||||
converter.parse(sampler, body.getBodyDataByType(), config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.BinaryBody;
|
||||
import io.metersphere.api.dto.request.http.body.BodyFile;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||
|
||||
/**
|
||||
* 处理 Binary 参数
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-14 19:55
|
||||
*/
|
||||
public class MsBinaryBodyConverter extends MsBodyConverter<BinaryBody> {
|
||||
@Override
|
||||
public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) {
|
||||
BodyFile bodyFile = body.getBodyFile();
|
||||
HTTPFileArg httpFileArg = getHttpFileArg(bodyFile);
|
||||
sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.BodyFile;
|
||||
import io.metersphere.api.dto.request.http.body.WWWFormKV;
|
||||
import io.metersphere.jmeter.mock.Mock;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.sdk.constants.LocalRepositoryDir;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPArgument;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-10-27 10:07
|
||||
* <p>
|
||||
* body 解析器
|
||||
*/
|
||||
public abstract class MsBodyConverter<T> {
|
||||
|
||||
/**
|
||||
* 解析对应的请求体参数
|
||||
* @param sampler
|
||||
* @param body
|
||||
* @param config
|
||||
*/
|
||||
public abstract void parse(HTTPSamplerProxy sampler, T body, ParameterConfig config);
|
||||
|
||||
/**
|
||||
* 解析文本类型的 kv 参数
|
||||
* @param textFromValues
|
||||
* @return
|
||||
*/
|
||||
protected Arguments getArguments(List<? extends WWWFormKV> textFromValues) {
|
||||
Arguments arguments = new Arguments();
|
||||
textFromValues.forEach(formDataKV -> {
|
||||
// 处理 mock 函数
|
||||
String value = Mock.buildFunctionCallString(formDataKV.getValue());
|
||||
if (value == null) {
|
||||
value = StringUtils.EMPTY;
|
||||
}
|
||||
HTTPArgument httpArgument = new HTTPArgument(formDataKV.getKey(), value);
|
||||
httpArgument.setAlwaysEncoded(formDataKV.getEncode());
|
||||
if (StringUtils.isNotBlank(formDataKV.getContentType())) {
|
||||
httpArgument.setContentType(formDataKV.getContentType());
|
||||
}
|
||||
arguments.addArgument(httpArgument);
|
||||
});
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 form-data 和 binary 类型的文件转换为 jmeter 的 HTTPFileArg
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
protected HTTPFileArg getHttpFileArg(BodyFile file) {
|
||||
String fileId = file.getFileId();
|
||||
String fileName = file.getFileName();
|
||||
// 在对应目录下创建文件ID目录,将文件放入
|
||||
String path = LocalRepositoryDir.getSystemCacheDir() + '/' + fileId + '/' + fileName;
|
||||
if (!StringUtils.equals(File.separator, "/")) {
|
||||
// windows 系统下运行,将 / 转换为 \,否则jmeter报错
|
||||
path = path.replace("/", File.separator);
|
||||
}
|
||||
String mimetype = ContentType.APPLICATION_OCTET_STREAM.getMimeType();
|
||||
HTTPFileArg fileArg = new HTTPFileArg(path, StringUtils.EMPTY, mimetype);
|
||||
return fileArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文本中的 @xxx 转换成 ${__Mock(@xxx)}
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
protected String parseTextMock(String text) {
|
||||
String pattern = "@[a-zA-Z]*";
|
||||
Pattern regex = Pattern.compile(pattern);
|
||||
Matcher matcher = regex.matcher(text);
|
||||
while (matcher.find()) {
|
||||
text = text.replace(matcher.group(), "${__Mock(" + matcher.group() + ")}");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理raw格式参数
|
||||
* 包含了 json 等格式
|
||||
* @param sampler
|
||||
* @param raw
|
||||
*/
|
||||
protected static void handleRowBody(HTTPSamplerProxy sampler, String raw) {
|
||||
Arguments arguments = new Arguments();
|
||||
HTTPArgument httpArgument = new HTTPArgument();
|
||||
httpArgument.setValue(raw);
|
||||
httpArgument.setAlwaysEncoded(false);
|
||||
httpArgument.setEnabled(true);
|
||||
arguments.addArgument(httpArgument);
|
||||
sampler.setPostBodyRaw(true);
|
||||
sampler.setArguments(arguments);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-21 19:19
|
||||
*/
|
||||
public class MsBodyConverterFactory {
|
||||
|
||||
private static Map<Class, MsBodyConverter> converterMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
converterMap.put(RawBody.class, new MsRawBodyConverter());
|
||||
converterMap.put(NoneBody.class, new MsNoneBodyConverter());
|
||||
converterMap.put(FormDataBody.class, new MsFormDataBodyConverter());
|
||||
converterMap.put(WWWFormBody.class, new MsWWWFormBodyConverter());
|
||||
converterMap.put(JsonBody.class, new MsJsonBodyConverter());
|
||||
converterMap.put(XmlBody.class, new MsXmlBodyConverter());
|
||||
converterMap.put(BinaryBody.class, new MsBinaryBodyConverter());
|
||||
}
|
||||
|
||||
public static MsBodyConverter getConverter(Class bodyClassByType) {
|
||||
return converterMap.get(bodyClassByType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.FormDataBody;
|
||||
import io.metersphere.api.dto.request.http.body.FormDataKV;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 处理 form-data 类型的请求体
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-14 15:18
|
||||
*/
|
||||
public class MsFormDataBodyConverter extends MsBodyConverter<FormDataBody> {
|
||||
|
||||
@Override
|
||||
public void parse(HTTPSamplerProxy sampler, FormDataBody body, ParameterConfig config) {
|
||||
List<FormDataKV> fromValues = body.getFromValues();
|
||||
List<FormDataKV> validFromValues = fromValues.stream().filter(FormDataKV::isValid).collect(Collectors.toList());
|
||||
List<FormDataKV> fileFromValues = validFromValues.stream().filter(FormDataKV::isFile).collect(Collectors.toList());
|
||||
List<FormDataKV> textFromValues = validFromValues.stream().filter(kv -> !kv.isFile()).collect(Collectors.toList());
|
||||
sampler.setDoMultipart(true);
|
||||
sampler.setHTTPFiles(getHttpFileArg(fileFromValues));
|
||||
sampler.setArguments(getArguments(textFromValues));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析文件类型的参数
|
||||
* @param fileFromValues
|
||||
* @return
|
||||
*/
|
||||
private HTTPFileArg[] getHttpFileArg(List<FormDataKV> fileFromValues) {
|
||||
if (CollectionUtils.isEmpty(fileFromValues)) {
|
||||
return new HTTPFileArg[0];
|
||||
}
|
||||
List<HTTPFileArg> list = new ArrayList<>();
|
||||
if (fileFromValues != null) {
|
||||
fileFromValues.forEach(formDataKV -> {
|
||||
String paramName = formDataKV.getKey();
|
||||
formDataKV.getFiles().forEach(file -> {
|
||||
HTTPFileArg fileArg = getHttpFileArg(file);
|
||||
fileArg.setParamName(paramName);
|
||||
String mimetype = formDataKV.getContentType();
|
||||
if (StringUtils.isBlank(mimetype)) {
|
||||
fileArg.setMimeType(mimetype);
|
||||
}
|
||||
list.add(fileArg);
|
||||
});
|
||||
});
|
||||
}
|
||||
return list.toArray(new HTTPFileArg[0]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.JsonBody;
|
||||
import io.metersphere.jmeter.mock.Mock;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-14 21:15
|
||||
*/
|
||||
public class MsJsonBodyConverter extends MsBodyConverter<JsonBody> {
|
||||
@Override
|
||||
public void parse(HTTPSamplerProxy sampler, JsonBody body, ParameterConfig config) {
|
||||
sampler.setPostBodyRaw(true);
|
||||
try {
|
||||
String raw = null;
|
||||
if (body.getEnableJsonSchema()) {
|
||||
// todo jsonSchema
|
||||
// JSONSchemaBuilder.generator(JSONUtil.toJSONString(this.getJsonSchema()))
|
||||
// raw = StringEscapeUtils.unescapeJava();
|
||||
} else {
|
||||
raw = parseJsonMock(body.getJsonValue());
|
||||
}
|
||||
handleRowBody(sampler, raw);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("json mock value is abnormal", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将json中的 @xxx 转换成 ${__Mock(@xxx)}
|
||||
* @param jsonStr
|
||||
* @return
|
||||
*/
|
||||
private String parseJsonMock(String jsonStr) {
|
||||
if (StringUtils.isNotEmpty(jsonStr)) {
|
||||
String value = StringUtils.chomp(jsonStr.trim());
|
||||
try {
|
||||
if (StringUtils.startsWith(value, "[") && StringUtils.endsWith(value, "]")) {
|
||||
List list = JSON.parseArray(jsonStr);
|
||||
parseMock(list);
|
||||
return JSON.toJSONString(list);
|
||||
} else {
|
||||
Map<String, Object> map = JSON.parseObject(jsonStr, Map.class);
|
||||
parseMock(map);
|
||||
return JSON.toJSONString(map);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 如果json串中的格式不是标准的json格式,正则替换变量
|
||||
return parseTextMock(jsonStr);
|
||||
}
|
||||
}
|
||||
return jsonStr;
|
||||
}
|
||||
|
||||
private void parseMock(List list) {
|
||||
Map<Integer, String> replaceDataMap = new HashMap<>();
|
||||
for (int index = 0; index < list.size(); index++) {
|
||||
Object obj = list.get(index);
|
||||
if (obj instanceof Map) {
|
||||
parseMock((Map) obj);
|
||||
} else if (obj instanceof String) {
|
||||
if (StringUtils.isNotBlank((String) obj)) {
|
||||
String str = Mock.buildFunctionCallString((String) obj);
|
||||
replaceDataMap.put(index, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Map.Entry<Integer, String> entry : replaceDataMap.entrySet()) {
|
||||
int replaceIndex = entry.getKey();
|
||||
String replaceStr = entry.getValue();
|
||||
list.set(replaceIndex, replaceStr);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseMock(Map map) {
|
||||
for (Object key : map.keySet()) {
|
||||
Object value = map.get(key);
|
||||
if (value instanceof List) {
|
||||
parseMock((List) value);
|
||||
} else if (value instanceof Map) {
|
||||
parseMock((Map) value);
|
||||
} else if (value instanceof String) {
|
||||
if (StringUtils.isNotBlank((String) value)) {
|
||||
value = Mock.buildFunctionCallString((String) value);
|
||||
}
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.NoneBody;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-14 21:15
|
||||
*/
|
||||
public class MsNoneBodyConverter extends MsBodyConverter<NoneBody> {
|
||||
@Override
|
||||
public void parse(HTTPSamplerProxy sampler, NoneBody body, ParameterConfig config) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.RawBody;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
|
||||
/**
|
||||
* 处理 Raw 格式参数
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-14 21:15
|
||||
*/
|
||||
public class MsRawBodyConverter extends MsBodyConverter<RawBody> {
|
||||
@Override
|
||||
public void parse(HTTPSamplerProxy sampler, RawBody body, ParameterConfig config) {
|
||||
handleRowBody(sampler, body.getValue());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.FormDataKV;
|
||||
import io.metersphere.api.dto.request.http.body.WWWFormBody;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-14 20:34
|
||||
*/
|
||||
public class MsWWWFormBodyConverter extends MsBodyConverter<WWWFormBody> {
|
||||
@Override
|
||||
public void parse(HTTPSamplerProxy sampler, WWWFormBody body, ParameterConfig config) {
|
||||
List<FormDataKV> fromValues = body.getFromValues();
|
||||
List<FormDataKV> validFromValues = fromValues.stream().filter(FormDataKV::isValid).collect(Collectors.toList());
|
||||
sampler.setArguments(getArguments(validFromValues));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.api.parser.jmeter.body;
|
||||
|
||||
import io.metersphere.api.dto.request.http.body.XmlBody;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-14 21:15
|
||||
*/
|
||||
public class MsXmlBodyConverter extends MsBodyConverter<XmlBody> {
|
||||
@Override
|
||||
public void parse(HTTPSamplerProxy sampler, XmlBody body, ParameterConfig config) {
|
||||
handleRowBody(sampler, body.getValue());
|
||||
}
|
||||
}
|
|
@ -7,11 +7,16 @@ import io.metersphere.api.dto.debug.ApiResourceRunRequest;
|
|||
import io.metersphere.api.parser.TestElementParser;
|
||||
import io.metersphere.api.parser.TestElementParserFactory;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.domain.ProjectApplication;
|
||||
import io.metersphere.project.service.FileAssociationService;
|
||||
import io.metersphere.project.service.FileManagementService;
|
||||
import io.metersphere.project.service.FileMetadataService;
|
||||
import io.metersphere.project.service.ProjectApplicationService;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.constants.StorageType;
|
||||
import io.metersphere.sdk.dto.api.task.ApiExecuteFileInfo;
|
||||
import io.metersphere.sdk.dto.api.task.TaskRequest;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.*;
|
||||
|
@ -25,6 +30,7 @@ import io.metersphere.system.service.TestResourcePoolService;
|
|||
import io.metersphere.system.utils.TaskRunnerClient;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
|
@ -37,6 +43,8 @@ import java.security.SecureRandom;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.metersphere.api.controller.result.ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR;
|
||||
|
||||
|
@ -59,6 +67,15 @@ public class ApiExecuteService {
|
|||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Resource
|
||||
private JmeterProperties jmeterProperties;
|
||||
@Resource
|
||||
private ApiFileResourceService apiFileResourceService;
|
||||
@Resource
|
||||
private FileAssociationService fileAssociationService;
|
||||
@Resource
|
||||
private FileMetadataService fileMetadataService;
|
||||
@Resource
|
||||
private FileManagementService fileManagementService;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
|
@ -89,24 +106,24 @@ public class ApiExecuteService {
|
|||
public void debug(ApiResourceRunRequest request) {
|
||||
TestResourceDTO resourcePoolDTO = getAvailableResourcePoolDTO(request.getProjectId());
|
||||
String reportId = request.getReportId();
|
||||
String testId = request.getTestId();
|
||||
String testId = request.getTestId();
|
||||
|
||||
TaskRequest taskRequest = new TaskRequest();
|
||||
BeanUtils.copyBean(taskRequest, request);
|
||||
|
||||
String msUrl = systemParameterService.getBaseInfo().getUrl();
|
||||
taskRequest.setKafkaConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(KafkaConfig.getKafkaConfig())));
|
||||
taskRequest.setMinioConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(getMinio())));
|
||||
taskRequest.setMsUrl(msUrl);
|
||||
taskRequest.setReportId(reportId);
|
||||
taskRequest.setMsUrl(systemParameterService.getBaseInfo().getUrl());
|
||||
taskRequest.setRealTime(true);
|
||||
|
||||
// todo 环境配置
|
||||
// EnvironmentRequest environmentRequest = environmentService.get(request.getEnvironmentId());
|
||||
// todo 误报
|
||||
// todo 获取接口插件和jar包
|
||||
// todo 处理公共脚本
|
||||
// 设置执行文件参数
|
||||
setTaskFileParam(request, taskRequest);
|
||||
|
||||
// todo 环境配置
|
||||
// EnvironmentInfoDTO environmentInfoDTO = environmentService.get(request.getEnvironmentId());
|
||||
// todo 误报
|
||||
// todo 获取接口插件和jar包
|
||||
// todo 处理公共脚本
|
||||
// todo 接口用例 method 获取定义中的数据库字段
|
||||
ParameterConfig parameterConfig = new ParameterConfig();
|
||||
parameterConfig.setReportId(reportId);
|
||||
String executeScript = parseExecuteScript(request.getRequest(), parameterConfig);
|
||||
|
@ -130,8 +147,94 @@ public class ApiExecuteService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 给 taskRequest 设置文件相关参数
|
||||
*
|
||||
* @param request
|
||||
* @param taskRequest
|
||||
*/
|
||||
private void setTaskFileParam(ApiResourceRunRequest request, TaskRequest taskRequest) {
|
||||
// 查询通过本地上传的文件
|
||||
List<ApiExecuteFileInfo> localFiles = apiFileResourceService.getByResourceId(request.getId()).
|
||||
stream()
|
||||
.map(file -> {
|
||||
ApiExecuteFileInfo apiExecuteFileInfo = getApiExecuteFileInfo(file.getFileId(), file.getFileName(), file.getProjectId());
|
||||
// 本地上传的文件需要 resourceId 查询对应的目录
|
||||
apiExecuteFileInfo.setResourceId(request.getId());
|
||||
return apiExecuteFileInfo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
taskRequest.setLocalFiles(localFiles);
|
||||
|
||||
// 查询关联的文件管理的文件
|
||||
List<ApiExecuteFileInfo> refFiles = fileAssociationService.getFiles(request.getId()).
|
||||
stream()
|
||||
.map(file -> {
|
||||
ApiExecuteFileInfo refFileInfo = getApiExecuteFileInfo(file.getFileId(), file.getFileName(),
|
||||
file.getProjectId(), file.getStorage());
|
||||
if (StorageType.isGit(file.getStorage())) {
|
||||
// 设置Git信息
|
||||
refFileInfo.setFileMetadataRepositoryDTO(fileManagementService.getFileMetadataRepositoryDTO(file.getMetadataId()));
|
||||
refFileInfo.setFileModuleRepositoryDTO(fileManagementService.getFileModuleRepositoryDTO(file.getModuleId()));
|
||||
}
|
||||
return refFileInfo;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
// 处理没有保存的临时文件
|
||||
List<String> tempFileIds = request.getTempFileIds();
|
||||
if (CollectionUtils.isNotEmpty(tempFileIds)) {
|
||||
// 查询这些文件有哪些是关联文件管理的文件
|
||||
List<ApiExecuteFileInfo> refTempFiles = fileMetadataService.getByFileIds(tempFileIds)
|
||||
.stream()
|
||||
.map(file -> {
|
||||
String fileName = file.getName();
|
||||
if (StringUtils.isNotBlank(file.getType())) {
|
||||
fileName += "." + file.getType();
|
||||
}
|
||||
ApiExecuteFileInfo tempFileInfo = getApiExecuteFileInfo(file.getId(), fileName,
|
||||
file.getProjectId(), file.getStorage());
|
||||
if (StorageType.isGit(file.getStorage())) {
|
||||
// 设置Git信息
|
||||
tempFileInfo.setFileMetadataRepositoryDTO(fileManagementService.getFileMetadataRepositoryDTO(file.getId()));
|
||||
tempFileInfo.setFileModuleRepositoryDTO(fileManagementService.getFileModuleRepositoryDTO(file.getModuleId()));
|
||||
}
|
||||
return tempFileInfo;
|
||||
}).collect(Collectors.toList());
|
||||
// 添加临时的文件管理的文件
|
||||
refFiles.addAll(refTempFiles);
|
||||
|
||||
Set<String> refTempFileIds = refTempFiles.stream().map(ApiExecuteFileInfo::getFileId).collect(Collectors.toSet());
|
||||
// 去掉文件管理的文件,即通过本地上传的临时文件
|
||||
List<ApiExecuteFileInfo> localTempFiles = tempFileIds.stream()
|
||||
.filter(tempFileId -> !refTempFileIds.contains(tempFileId))
|
||||
.map(tempFileId -> {
|
||||
String fileName = apiFileResourceService.getTempFileNameByFileId(tempFileId);
|
||||
ApiExecuteFileInfo apiExecuteFileInfo = getApiExecuteFileInfo(tempFileId, fileName, request.getProjectId());
|
||||
return apiExecuteFileInfo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
taskRequest.setLocalTempFiles(localTempFiles);
|
||||
}
|
||||
|
||||
taskRequest.setRefFiles(refFiles);
|
||||
}
|
||||
|
||||
private static ApiExecuteFileInfo getApiExecuteFileInfo(String fileId, String fileName, String projectId) {
|
||||
return getApiExecuteFileInfo(fileId, fileName, projectId, StorageType.MINIO.name());
|
||||
}
|
||||
|
||||
private static ApiExecuteFileInfo getApiExecuteFileInfo(String fileId, String fileName, String projectId, String storage) {
|
||||
ApiExecuteFileInfo apiExecuteFileInfo = new ApiExecuteFileInfo();
|
||||
apiExecuteFileInfo.setStorage(storage);
|
||||
apiExecuteFileInfo.setFileName(fileName);
|
||||
apiExecuteFileInfo.setFileId(fileId);
|
||||
apiExecuteFileInfo.setProjectId(projectId);
|
||||
return apiExecuteFileInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成执行脚本
|
||||
*
|
||||
* @param testElementStr
|
||||
* @param msParameter
|
||||
* @return
|
||||
|
@ -155,6 +258,7 @@ public class ApiExecuteService {
|
|||
|
||||
/**
|
||||
* 获取当前项目配置的接口默认资源池
|
||||
*
|
||||
* @param projectId
|
||||
* @param
|
||||
*/
|
||||
|
|
|
@ -113,10 +113,12 @@ public class ApiDebugService {
|
|||
apiDebugMapper.updateByPrimaryKeySelective(apiDebug);
|
||||
// todo 校验 moduleId
|
||||
|
||||
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||
apiDebugBlob.setId(request.getId());
|
||||
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
||||
apiDebugBlobMapper.updateByPrimaryKeySelective(apiDebugBlob);
|
||||
if (StringUtils.isNotBlank(request.getRequest())) {
|
||||
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||
apiDebugBlob.setId(request.getId());
|
||||
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
||||
apiDebugBlobMapper.updateByPrimaryKeySelective(apiDebugBlob);
|
||||
}
|
||||
|
||||
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(originApiDebug.getId(), originApiDebug.getProjectId(), updateUser);
|
||||
resourceUpdateRequest.setUploadFileIds(request.getUploadFileIds());
|
||||
|
@ -159,6 +161,7 @@ public class ApiDebugService {
|
|||
throw new MSException(API_DEBUG_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
private ApiDebug checkResourceExist(String id) {
|
||||
return ServiceUtils.checkResourceExist(apiDebugMapper.selectByPrimaryKey(id), "permission.system_api_debug.name");
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.api.domain.ApiFileResource;
|
|||
import io.metersphere.api.dto.debug.*;
|
||||
import io.metersphere.api.dto.request.MsScenario;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.dto.request.http.body.Body;
|
||||
import io.metersphere.api.mapper.ApiDebugBlobMapper;
|
||||
import io.metersphere.api.mapper.ApiDebugMapper;
|
||||
import io.metersphere.api.parser.ImportParserFactory;
|
||||
|
@ -29,9 +30,10 @@ import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
|||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.constants.ResourcePoolTypeEnum;
|
||||
import io.metersphere.sdk.file.FileCenter;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.FileAssociationSourceUtil;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
|
@ -42,8 +44,6 @@ import io.metersphere.system.domain.TestResourcePoolOrganizationExample;
|
|||
import io.metersphere.system.dto.pool.TestResourceDTO;
|
||||
import io.metersphere.system.dto.pool.TestResourceNodeDTO;
|
||||
import io.metersphere.system.dto.pool.TestResourcePoolDTO;
|
||||
import io.metersphere.sdk.file.FileCenter;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.mapper.TestResourcePoolBlobMapper;
|
||||
import io.metersphere.system.mapper.TestResourcePoolMapper;
|
||||
|
@ -339,7 +339,7 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
*/
|
||||
private static void assertLinkFile(String id, List<String> fileIds) {
|
||||
FileAssociationService fileAssociationService = CommonBeanFactory.getBean(FileAssociationService.class);
|
||||
List<String> linkFileIds = fileAssociationService.getFiles(id, FileAssociationSourceUtil.SOURCE_TYPE_API_DEBUG)
|
||||
List<String> linkFileIds = fileAssociationService.getFiles(id)
|
||||
.stream()
|
||||
.map(FileInfo::getFileId)
|
||||
.toList();
|
||||
|
@ -408,6 +408,42 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
// @@请求成功
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
// 测试 FORM_DATA
|
||||
MockMultipartFile file = getMockMultipartFile();
|
||||
String fileId = doUploadTempFile(file);
|
||||
request.setTempFileIds(List.of(fileId, fileMetadataId));
|
||||
msHTTPElement = MsHTTPElementTest.getMsHttpElement();
|
||||
Body generalBody = MsHTTPElementTest.getGeneralBody();
|
||||
generalBody.setBodyType(Body.BodyType.FORM_DATA.name());
|
||||
msHTTPElement.setBody(generalBody);
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
// 测试 WWW_FORM
|
||||
generalBody.setBodyType(Body.BodyType.WWW_FORM.name());
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
// 测试 BINARY
|
||||
generalBody.setBodyType(Body.BodyType.BINARY.name());
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
// 测试 JSON
|
||||
generalBody.setBodyType(Body.BodyType.JSON.name());
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
// 测试 XML
|
||||
generalBody.setBodyType(Body.BodyType.XML.name());
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
// 测试 XML
|
||||
generalBody.setBodyType(Body.BodyType.RAW.name());
|
||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
// 增加覆盖率
|
||||
new TestElementParserFactory();
|
||||
new ImportParserFactory();
|
||||
|
|
|
@ -415,7 +415,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
*/
|
||||
private static void assertLinkFile(String id, List<String> fileIds) {
|
||||
FileAssociationService fileAssociationService = CommonBeanFactory.getBean(FileAssociationService.class);
|
||||
List<String> linkFileIds = fileAssociationService.getFiles(id, FileAssociationSourceUtil.SOURCE_TYPE_API_DEFINITION)
|
||||
List<String> linkFileIds = fileAssociationService.getFiles(id)
|
||||
.stream()
|
||||
.map(FileInfo::getFileId)
|
||||
.toList();
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.api.controller;
|
|||
import io.metersphere.api.controller.param.ApiTestCaseAddRequestDefinition;
|
||||
import io.metersphere.api.domain.*;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.mapper.*;
|
||||
import io.metersphere.api.service.ApiFileResourceService;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
|
@ -17,18 +18,16 @@ import io.metersphere.sdk.constants.PermissionConstants;
|
|||
import io.metersphere.sdk.constants.SessionConstants;
|
||||
import io.metersphere.sdk.domain.Environment;
|
||||
import io.metersphere.sdk.domain.EnvironmentExample;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.sdk.file.FileCenter;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.sdk.file.MinioRepository;
|
||||
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.FileAssociationSourceUtil;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||
import io.metersphere.sdk.file.FileCenter;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.sdk.file.MinioRepository;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.uid.NumGenerator;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
|
@ -240,7 +239,7 @@ public class ApiTestCaseControllerTests extends BaseTest {
|
|||
*/
|
||||
private static void assertLinkFile(String id, List<String> fileIds) {
|
||||
FileAssociationService fileAssociationService = CommonBeanFactory.getBean(FileAssociationService.class);
|
||||
List<String> linkFileIds = fileAssociationService.getFiles(id, FileAssociationSourceUtil.SOURCE_TYPE_API_TEST_CASE)
|
||||
List<String> linkFileIds = fileAssociationService.getFiles(id)
|
||||
.stream()
|
||||
.map(FileInfo::getFileId)
|
||||
.toList();
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package io.metersphere.api.controller;
|
||||
|
||||
import io.metersphere.api.dto.definition.HttpResponse;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.constants.MsAssertionCondition;
|
||||
import io.metersphere.api.dto.request.assertion.*;
|
||||
import io.metersphere.api.dto.request.assertion.body.*;
|
||||
import io.metersphere.api.dto.request.http.*;
|
||||
|
@ -16,6 +13,9 @@ import io.metersphere.api.dto.request.processors.*;
|
|||
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 io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.constants.MsAssertionCondition;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -33,9 +33,14 @@ public class MsHTTPElementTest {
|
|||
|
||||
@Test
|
||||
public void bodyTest() {
|
||||
|
||||
MsHTTPElement msHTTPElement = getMsHttpElement();
|
||||
msHTTPElement.setBody(getGeneralBody());
|
||||
String json = ApiDataUtils.toJSONString(msHTTPElement);
|
||||
Assertions.assertNotNull(json);
|
||||
Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement);
|
||||
}
|
||||
|
||||
public static Body getGeneralBody() {
|
||||
Body body = new Body();
|
||||
body.setBodyType(Body.BodyType.FORM_DATA.name());
|
||||
|
||||
|
@ -49,8 +54,14 @@ public class MsHTTPElementTest {
|
|||
formDataKV.setParamType("text");
|
||||
formDataKV.setDescription("test");
|
||||
formDataKV.setRequired(true);
|
||||
formDataKV.setValue("value");
|
||||
formDataKV.setValue("@email");
|
||||
formDataKV.setKey("key");
|
||||
FormDataKV formDataFileKV = new FormDataKV();
|
||||
BodyFile bodyFile = new BodyFile();
|
||||
bodyFile.setFileId("aaa");
|
||||
bodyFile.setFileName("aaa");
|
||||
formDataFileKV.setFiles(List.of(bodyFile));
|
||||
formDataFileKV.setKey("fileKey");
|
||||
formDataBody.setFromValues(List.of(formDataKV));
|
||||
body.setFormDataBody(formDataBody);
|
||||
|
||||
|
@ -60,6 +71,7 @@ public class MsHTTPElementTest {
|
|||
|
||||
JsonBody jsonBody = new JsonBody();
|
||||
jsonBody.setJsonSchema("{}");
|
||||
jsonBody.setEnableJsonSchema(false);
|
||||
body.setJsonBody(jsonBody);
|
||||
|
||||
body.setNoneBody(new NoneBody());
|
||||
|
@ -73,14 +85,10 @@ public class MsHTTPElementTest {
|
|||
body.setXmlBody(xmlBody);
|
||||
|
||||
BinaryBody binaryBody = new BinaryBody();
|
||||
binaryBody.setFileId("sdfsf2222");
|
||||
binaryBody.setFileName("a.png");
|
||||
binaryBody.setBodyFile(bodyFile);
|
||||
body.setBinaryBody(binaryBody);
|
||||
|
||||
msHTTPElement.setBody(body);
|
||||
String json = ApiDataUtils.toJSONString(msHTTPElement);
|
||||
Assertions.assertNotNull(json);
|
||||
Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement);
|
||||
return body;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -128,7 +128,7 @@ public class FunctionalCaseAttachmentService {
|
|||
}));
|
||||
|
||||
//获取关联的附件信息
|
||||
List<FileInfo> files = fileAssociationService.getFiles(functionalCaseDetailDTO.getId(), FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE);
|
||||
List<FileInfo> files = fileAssociationService.getFiles(functionalCaseDetailDTO.getId());
|
||||
List<FunctionalCaseAttachmentDTO> filesDTOs = new ArrayList<>(Lists.transform(files, (fileInfo) -> {
|
||||
FunctionalCaseAttachmentDTO attachmentDTO = new FunctionalCaseAttachmentDTO();
|
||||
BeanUtils.copyBean(attachmentDTO, fileInfo);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.project.controller;
|
||||
|
||||
import io.metersphere.project.dto.environment.EnvironmentInfoDTO;
|
||||
import io.metersphere.project.dto.environment.*;
|
||||
import io.metersphere.project.dto.environment.datasource.DataSource;
|
||||
import io.metersphere.project.dto.environment.ssl.KeyStoreEntry;
|
||||
|
|
|
@ -36,4 +36,15 @@ public class FileInfo implements Serializable {
|
|||
@Schema(description = "创建时间")
|
||||
private Long createTime;
|
||||
|
||||
@Schema(description = "文件存储方式")
|
||||
private String storage;
|
||||
|
||||
@Schema(description = "项目ID")
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "模块ID")
|
||||
private String moduleId;
|
||||
|
||||
@Schema(description = "文件资源ID")
|
||||
private String metadataId;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public interface ExtFileAssociationMapper {
|
|||
FileAssociationSource selectNameBySourceTableAndId(@Param("querySql") String querySql, @Param("sourceId") String sourceId);
|
||||
List<FileAssociationSource> selectAssociationSourceBySourceTableAndIdList(@Param("querySql") String querySql, @Param("idList") List<String> sourceIdList);
|
||||
|
||||
List<FileInfo> selectAssociationFileInfo(@Param("sourceId") String sourceId, @Param("sourceType") String sourceType);
|
||||
List<FileInfo> selectAssociationFileInfo(@Param("sourceId") String sourceId);
|
||||
|
||||
List<FileAssociation> selectFileIdsBySourceId(@Param("sourceIds")List<String> sourceIds, @Param("sourceType")String sourceType);
|
||||
}
|
||||
|
|
|
@ -19,8 +19,12 @@
|
|||
SELECT
|
||||
file_association.id AS id,
|
||||
file_association.file_id AS fileId,
|
||||
CONCAT( file_metadata.`name`, '.', file_metadata.type ) AS fileName,
|
||||
CONCAT( file_metadata.`name`, IF(LENGTH(file_metadata.type) = 0, '', '.'), file_metadata.type ) AS fileName,
|
||||
file_metadata.size AS size,
|
||||
file_metadata.storage,
|
||||
file_metadata.project_id,
|
||||
file_metadata.module_id,
|
||||
file_metadata.id as metadataId,
|
||||
'false' AS local,
|
||||
file_association.create_user AS createUser,
|
||||
file_association.create_time AS createTime
|
||||
|
@ -29,7 +33,6 @@
|
|||
LEFT JOIN file_metadata ON file_association.file_id = file_metadata.id
|
||||
WHERE
|
||||
file_association.source_id = #{sourceId}
|
||||
AND file_association.source_type = #{sourceType}
|
||||
</select>
|
||||
|
||||
<select id="selectFileIdsBySourceId" resultType="io.metersphere.project.domain.FileAssociation">
|
||||
|
|
|
@ -25,7 +25,7 @@ public class CommandService {
|
|||
|
||||
public static String createFile(MultipartFile bodyFile) {
|
||||
MsFileUtils.validateFileName(bodyFile.getOriginalFilename());
|
||||
String dir = LocalRepositoryDir.getBodyEnvironmentTmpDir();
|
||||
String dir = LocalRepositoryDir.getSystemTempDir();
|
||||
File fileDir = new File(dir);
|
||||
if (!fileDir.exists()) {
|
||||
fileDir.mkdirs();
|
||||
|
|
|
@ -337,11 +337,10 @@ public class FileAssociationService {
|
|||
* 获取文件列表接口
|
||||
*
|
||||
* @param sourceId
|
||||
* @param sourceType
|
||||
* @return
|
||||
*/
|
||||
public List<FileInfo> getFiles(String sourceId, String sourceType) {
|
||||
return extFileAssociationMapper.selectAssociationFileInfo(sourceId, sourceType);
|
||||
public List<FileInfo> getFiles(String sourceId) {
|
||||
return extFileAssociationMapper.selectAssociationFileInfo(sourceId);
|
||||
}
|
||||
|
||||
public List<FileAssociation> getFileAssociations(List<String> sourceIds, String sourceType) {
|
||||
|
|
|
@ -172,19 +172,27 @@ public class FileManagementService {
|
|||
fileRequest.setStorage(fileMetadata.getStorage());
|
||||
//获取git文件下载
|
||||
if (StringUtils.equals(fileMetadata.getStorage(), StorageType.GIT.name())) {
|
||||
FileModuleRepository fileModuleRepository = fileModuleRepositoryMapper.selectByPrimaryKey(fileMetadata.getModuleId());
|
||||
FileMetadataRepository fileMetadataRepository = fileMetadataRepositoryMapper.selectByPrimaryKey(fileMetadata.getId());
|
||||
|
||||
FileModuleRepositoryDTO repositoryDTO = new FileModuleRepositoryDTO();
|
||||
BeanUtils.copyBean(repositoryDTO, fileModuleRepository);
|
||||
FileMetadataRepositoryDTO metadataRepositoryDTO = new FileMetadataRepositoryDTO();
|
||||
BeanUtils.copyBean(metadataRepositoryDTO, fileMetadataRepository);
|
||||
FileModuleRepositoryDTO repositoryDTO = getFileModuleRepositoryDTO(fileMetadata.getModuleId());
|
||||
FileMetadataRepositoryDTO metadataRepositoryDTO = getFileMetadataRepositoryDTO(fileMetadata.getId());
|
||||
fileRequest.setGitFileRequest(repositoryDTO, metadataRepositoryDTO);
|
||||
}
|
||||
|
||||
return fileService.download(fileRequest);
|
||||
}
|
||||
|
||||
public FileMetadataRepositoryDTO getFileMetadataRepositoryDTO(String fileMetadataId) {
|
||||
FileMetadataRepository fileMetadataRepository = fileMetadataRepositoryMapper.selectByPrimaryKey(fileMetadataId);
|
||||
FileMetadataRepositoryDTO metadataRepositoryDTO = new FileMetadataRepositoryDTO();
|
||||
BeanUtils.copyBean(metadataRepositoryDTO, fileMetadataRepository);
|
||||
return metadataRepositoryDTO;
|
||||
}
|
||||
|
||||
public FileModuleRepositoryDTO getFileModuleRepositoryDTO(String moduleId) {
|
||||
FileModuleRepository fileModuleRepository = fileModuleRepositoryMapper.selectByPrimaryKey(moduleId);
|
||||
FileModuleRepositoryDTO repositoryDTO = new FileModuleRepositoryDTO();
|
||||
BeanUtils.copyBean(repositoryDTO, fileModuleRepository);
|
||||
return repositoryDTO;
|
||||
}
|
||||
|
||||
public byte[] getPreviewImg(FileMetadata fileMetadata) {
|
||||
FileRequest previewRequest = new FileRequest();
|
||||
|
|
|
@ -669,4 +669,10 @@ public class FileMetadataService {
|
|||
private String generateMinIOFilePath(String projectId) {
|
||||
return DefaultRepositoryDir.getFileManagementDir(projectId);
|
||||
}
|
||||
|
||||
public List<FileMetadata> getByFileIds(List<String> tempFileIds) {
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andIdIn(tempFileIds);
|
||||
return fileMetadataMapper.selectByExample(example);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.project.controller;
|
||||
|
||||
|
||||
import io.metersphere.project.dto.environment.EnvironmentInfoDTO;
|
||||
import io.metersphere.project.dto.environment.*;
|
||||
import io.metersphere.project.dto.environment.assertions.*;
|
||||
import io.metersphere.project.dto.environment.auth.AuthConfig;
|
||||
|
|
|
@ -2421,7 +2421,7 @@ public class FileManagementControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(91)
|
||||
public void testQuery() throws Exception {
|
||||
fileAssociationService.getFiles("TEST", FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE);
|
||||
fileAssociationService.getFiles("TEST");
|
||||
fileAssociationService.getFileAssociations(Collections.singletonList("TEST"), FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue