refactor(项目管理): 优化环境接口

This commit is contained in:
wxg0103 2024-01-12 16:00:02 +08:00 committed by wxg0103
parent 09cb3f254b
commit 9da60bcca2
57 changed files with 1314 additions and 614 deletions

View File

@ -231,5 +231,4 @@ public class ApiDefinitionController {
apiDefinitionService.saveOperationHistory(request);
}
}

View File

@ -1,7 +1,9 @@
package io.metersphere.project.controller;
import io.metersphere.project.dto.environment.EnvironmentFilterRequest;
import io.metersphere.project.dto.environment.EnvironmentImportRequest;
import io.metersphere.project.dto.environment.EnvironmentInfoDTO;
import io.metersphere.project.dto.environment.*;
import io.metersphere.project.dto.environment.EnvironmentRequest;
import io.metersphere.project.dto.environment.datasource.DataSource;
import io.metersphere.project.dto.environment.ssl.KeyStoreEntry;
import io.metersphere.project.service.CommandService;
@ -11,6 +13,7 @@ import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.metersphere.system.log.annotation.Log;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.security.CheckOwner;
@ -60,7 +63,7 @@ public class EnvironmentController {
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD)
@Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = EnvironmentLogService.class)
public Environment add(@Validated({Created.class}) @RequestPart(value = "request") EnvironmentRequest request,
@RequestPart(value = "file", required = false) List<MultipartFile> sslFiles) {
@RequestPart(value = "file", required = false) List<MultipartFile> sslFiles) {
return environmentService.add(request, SessionUtils.getUserId(), sslFiles);
}
@ -70,7 +73,7 @@ public class EnvironmentController {
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = EnvironmentLogService.class)
@CheckOwner(resourceId = "#request.id", resourceType = "environment")
public Environment update(@Validated({Updated.class}) @RequestPart("request") EnvironmentRequest request,
@RequestPart(value = "file", required = false) List<MultipartFile> sslFiles) {
@RequestPart(value = "file", required = false) List<MultipartFile> sslFiles) {
return environmentService.update(request, SessionUtils.getUserId(), sslFiles);
}
@ -107,8 +110,8 @@ public class EnvironmentController {
@PostMapping("/export")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_EXPORT)
@Operation(summary = "项目管理-环境-环境目录-导出")
public ResponseEntity<byte[]> export(@Validated @RequestBody EnvironmentExportRequest request) {
return environmentService.exportZip(request);
public ResponseEntity<byte[]> export(@Validated @RequestBody TableBatchProcessDTO request) {
return environmentService.exportJson(request, SessionUtils.getCurrentProjectId());
}
@PostMapping(value = "/get/entry")
@ -124,5 +127,4 @@ public class EnvironmentController {
environmentService.editPos(request);
}
}

View File

@ -1,21 +1,24 @@
package io.metersphere.project.controller;
import io.metersphere.project.dto.environment.GlobalParamsDTO;
import io.metersphere.project.dto.environment.GlobalParamsRequest;
import io.metersphere.project.service.GlobalParamsLogService;
import io.metersphere.project.service.GlobalParamsService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.utils.SessionUtils;
import io.metersphere.sdk.domain.ProjectParameters;
import io.metersphere.system.log.annotation.Log;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.utils.SessionUtils;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
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.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/project/global/params")
@ -29,7 +32,7 @@ public class GlobalParamsController {
@Operation(summary = "项目管理-环境-全局参数-新增")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD)
@Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = GlobalParamsLogService.class)
public GlobalParamsRequest add(@Validated({Created.class}) @RequestBody GlobalParamsRequest request) {
public ProjectParameters add(@Validated({Created.class}) @RequestBody GlobalParamsRequest request) {
return globalParamsService.add(request, SessionUtils.getUserId());
}
@ -37,16 +40,30 @@ public class GlobalParamsController {
@Operation(summary = "项目管理-环境-全局参数-修改")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE)
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = GlobalParamsLogService.class)
public GlobalParamsRequest update(@Validated({Updated.class}) @RequestBody GlobalParamsRequest request) {
public ProjectParameters update(@Validated({Updated.class}) @RequestBody GlobalParamsRequest request) {
return globalParamsService.update(request, SessionUtils.getUserId());
}
@GetMapping("/get/{projectId}")
@Operation(summary = "项目管理-环境-全局参数-详情")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ)
public GlobalParamsRequest get(@PathVariable String projectId) {
public GlobalParamsDTO get(@PathVariable String projectId) {
return globalParamsService.get(projectId);
}
@GetMapping("/export/{projectId}")
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_EXPORT)
@Operation(summary = "项目管理-环境-全局参数-导出")
public ResponseEntity<byte[]> export(@PathVariable String projectId) {
return globalParamsService.exportJson(projectId);
}
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
@RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_IMPORT)
@Operation(summary = "项目管理-环境-全局参数-导入")
public void create(@RequestPart(value = "file") MultipartFile file) {
globalParamsService.importData(file, SessionUtils.getUserId(), SessionUtils.getCurrentProjectId());
}
}

View File

@ -1,13 +1,13 @@
package io.metersphere.project.dto.environment;
import io.metersphere.project.dto.environment.assertions.EnvironmentAssertions;
import io.metersphere.project.dto.environment.assertion.MsAssertionConfig;
import io.metersphere.project.dto.environment.auth.AuthConfig;
import io.metersphere.project.dto.environment.common.CommonParams;
import io.metersphere.project.dto.environment.datasource.DataSource;
import io.metersphere.project.dto.environment.host.HostConfig;
import io.metersphere.project.dto.environment.http.HttpConfig;
import io.metersphere.project.dto.environment.script.post.EnvironmentPostScript;
import io.metersphere.project.dto.environment.script.pre.EnvironmentPreScript;
import io.metersphere.project.dto.environment.processors.post.EnvironmentPostScript;
import io.metersphere.project.dto.environment.processors.pre.EnvironmentPreScript;
import io.metersphere.project.dto.environment.variables.CommonVariables;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -37,7 +37,7 @@ public class EnvironmentConfig implements Serializable {
@Schema(description = "全局后置脚本")
private EnvironmentPostScript postScript;
@Schema(description = "全局断言")
private EnvironmentAssertions assertions;
private MsAssertionConfig assertions;
public EnvironmentConfig() {
@ -49,7 +49,7 @@ public class EnvironmentConfig implements Serializable {
this.authConfig = new AuthConfig();
this.preScript = new EnvironmentPreScript();
this.postScript = new EnvironmentPostScript();
this.assertions = new EnvironmentAssertions();
this.assertions = new MsAssertionConfig();
}
}

View File

@ -1,23 +0,0 @@
package io.metersphere.project.dto.environment;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
public class EnvironmentExportRequest extends TableBatchProcessDTO {
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{project_application.project_id.not_blank}")
@Size(min = 1, max = 50, message = "{project_parameters.project_id.length_range}")
private String projectId;
@Schema(description = "是否勾选全局参数", requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean globalParam = false;
@Schema(description = "是否勾选环境", requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean environment = false;
}

View File

@ -12,7 +12,7 @@ import java.util.List;
public class GlobalParams implements Serializable {
@Schema(description = "请求头")
private List<KeyValue> headers;
private List<KeyValueEnableParam> headers;
@Schema(description = "全局变量")
private List<CommonVariables> commonVariables;

View File

@ -0,0 +1,24 @@
package io.metersphere.project.dto.environment;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class GlobalParamsDTO implements Serializable {
@Schema(description = "ID")
private String id;
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
private String projectId;
@Schema(description = "全局参数")
private GlobalParams globalParams;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,15 @@
package io.metersphere.project.dto.environment;
import lombok.Data;
@Data
public class KeyValueEnableParam extends KeyValueParam {
/**
* 是否启用
*/
private Boolean enable = true;
/**
* 描述
*/
private String description;
}

View File

@ -0,0 +1,20 @@
package io.metersphere.project.dto.environment;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@Data
public class KeyValueParam {
/**
*
*/
private String key;
/**
*
*/
private String value;
public boolean isValid() {
return StringUtils.isNotBlank(key);
}
}

View File

@ -0,0 +1,29 @@
package io.metersphere.project.dto.environment.assertion;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
/**
* 断言
*/
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "assertionType")
@JsonSubTypes({
@JsonSubTypes.Type(value = MsResponseCodeAssertion.class),
@JsonSubTypes.Type(value = MsResponseHeaderAssertion.class),
@JsonSubTypes.Type(value = MsResponseBodyAssertion.class),
@JsonSubTypes.Type(value = MsResponseTimeAssertion.class),
@JsonSubTypes.Type(value = MsScriptAssertion.class),
@JsonSubTypes.Type(value = MsVariableAssertion.class),
})
public abstract class MsAssertion {
/**
* 是否启用
*/
private Boolean enable = true;
/**
* 断言名称
*/
private String name;
}

View File

@ -0,0 +1,13 @@
package io.metersphere.project.dto.environment.assertion;
import lombok.Data;
import java.util.List;
@Data
public class MsAssertionConfig {
/**
* 断言列表
*/
private List<MsAssertion> assertions;
}

View File

@ -0,0 +1,83 @@
package io.metersphere.project.dto.environment.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.project.dto.environment.assertion.body.MsDocumentAssertion;
import io.metersphere.project.dto.environment.assertion.body.MsJSONPathAssertion;
import io.metersphere.project.dto.environment.assertion.body.MsRegexAssertion;
import io.metersphere.project.dto.environment.assertion.body.MsXPathAssertion;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
@JsonTypeName("ENV_RESPONSE_BODY")
public class MsResponseBodyAssertion extends MsAssertion {
/**
* 断言类型
* 根据断言类型选择对应的断言
* 这里跟前端数据结构有差异
* 后端从设计层面支持多种断言前端只支持一种
* 同时切换可以同时持久化两种类型
*
* @see MsBodyAssertionType
*/
private String assertionBodyType;
/**
* jsonPath断言
*/
private MsJSONPathAssertion jsonPathAssertion;
/**
* xpath断言
*/
private MsXPathAssertion xpathAssertion;
/**
* 文档断言
*/
private MsDocumentAssertion documentAssertion;
/**
* 正则断言
*/
private MsRegexAssertion regexAssertion;
private static Map<MsBodyAssertionType, Class> bodyAssertionClassMap = new HashMap<>();
static {
bodyAssertionClassMap.put(MsBodyAssertionType.JSON_PATH, MsJSONPathAssertion.class);
bodyAssertionClassMap.put(MsBodyAssertionType.DOCUMENT, MsDocumentAssertion.class);
bodyAssertionClassMap.put(MsBodyAssertionType.REGEX, MsRegexAssertion.class);
bodyAssertionClassMap.put(MsBodyAssertionType.XPATH, MsXPathAssertion.class);
}
public Class getBodyAssertionClassByType() {
return bodyAssertionClassMap.get(MsBodyAssertionType.valueOf(assertionBodyType));
}
public Object getBodyAssertionDataByType() {
Map<MsBodyAssertionType, Object> boadyAssertionMap = new HashMap<>();
boadyAssertionMap.put(MsBodyAssertionType.JSON_PATH, jsonPathAssertion);
boadyAssertionMap.put(MsBodyAssertionType.DOCUMENT, documentAssertion);
boadyAssertionMap.put(MsBodyAssertionType.REGEX, regexAssertion);
boadyAssertionMap.put(MsBodyAssertionType.XPATH, xpathAssertion);
return boadyAssertionMap.get(MsBodyAssertionType.valueOf(assertionBodyType));
}
public enum MsBodyAssertionType {
/**
* 正则断言
*/
REGEX,
/**
* XPath断言
*/
XPATH,
/**
* JSONPath断言
*/
JSON_PATH,
/**
* 文档断言
*/
DOCUMENT
}
}

View File

@ -0,0 +1,22 @@
package io.metersphere.project.dto.environment.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Data;
@Data
@JsonTypeName("ENV_RESPONSE_CODE")
public class MsResponseCodeAssertion extends MsAssertion {
/**
* 匹配条件
* 不校验即忽略状态
* 选择其他条件时也忽略状态
* 不校验可搭配其他校验使用
*
* @see io.metersphere.sdk.constants.MsAssertionCondition
*/
private String condition;
/**
* 匹配值
*/
private String expectedValue;
}

View File

@ -0,0 +1,35 @@
package io.metersphere.project.dto.environment.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Data;
import java.util.List;
@Data
@JsonTypeName("ENV_RESPONSE_HEADER")
public class MsResponseHeaderAssertion extends MsAssertion {
private List<ResponseHeaderAssertionItem> assertions;
@Data
public static class ResponseHeaderAssertionItem {
/**
* 是否启用
*/
private Boolean enable = true;
/**
* 响应头
*/
private String header;
/**
* 匹配条件
* 值为 MsAssertionCondition
*/
private String condition;
/**
* 匹配值
*/
private String expectedValue;
}
}

View File

@ -0,0 +1,14 @@
package io.metersphere.project.dto.environment.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Data;
@Data
@JsonTypeName("ENV_RESPONSE_TIME")
public class MsResponseTimeAssertion extends MsAssertion {
/**
* 最大响应时间
* 响应时间在xx毫秒内
*/
private Long expectedValue;
}

View File

@ -0,0 +1,35 @@
package io.metersphere.project.dto.environment.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.project.dto.environment.KeyValueParam;
import io.metersphere.project.dto.environment.processors.ScriptProcessor;
import lombok.Data;
import java.util.List;
@Data
@JsonTypeName("ENV_SCRIPT_ASSERTION")
public class MsScriptAssertion extends MsAssertion {
/**
* 脚本内容
*/
private String script;
/**
* 脚本语言
*
* @see ScriptProcessor.ScriptLanguageType
*/
private String scriptLanguage;
/**
* 是否启用公共脚本
*/
private Boolean enableCommonScript;
/**
* 脚本ID
*/
private String scriptId;
/**
* 公共脚本入参
*/
private List<KeyValueParam> params;
}

View File

@ -0,0 +1,34 @@
package io.metersphere.project.dto.environment.assertion;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Data;
import java.util.List;
@Data
@JsonTypeName("ENV_VARIABLE")
public class MsVariableAssertion extends MsAssertion {
private List<VariableAssertionItem> variableAssertionItems;
@Data
public static class VariableAssertionItem {
/**
* 是否启用
*/
private Boolean enable = true;
/**
* 变量名
*/
private String variableName;
/**
* 匹配条件
* 值为 MsAssertionCondition
*/
private String condition;
/**
* 匹配值
*/
private String expectedValue;
}
}

View File

@ -0,0 +1,8 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
@Data
public abstract class MsBodyAssertionItem {
private Boolean enable = true;
}

View File

@ -0,0 +1,36 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
@Data
public class MsDocumentAssertion extends MsBodyAssertionItem {
/**
* 跟随定义的apiId
* 传空为不跟随接口定义
*/
private String followApiId;
/**
* 文档类型
* json 或者 xml
* 根据文档类型选择对应的文档
* 这里跟前端数据结构有差异
* 后端从设计层面支持多种文档格式前端只支持一种
* 同时切换可以同时持久化两种格式
*
* @see DocumentType
*/
private String documentType;
/**
* json格式的文档断言
*/
private MsDocumentAssertionElement jsonAssertion;
/**
* xml格式的文档断言
*/
private MsDocumentAssertionElement xmlAssertion;
public enum DocumentType {
JSON,
XML;
}
}

View File

@ -0,0 +1,44 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
import java.util.List;
@Data
public class MsDocumentAssertionElement {
private String id;
/**
* 参数名
*/
private String paramName;
/**
* 必含
*/
private Boolean include = false;
/**
* 类型
*/
private String type;
/**
* 类型校验
*/
private Boolean typeVerification = false;
/**
* 匹配条件
*/
private String condition;
/**
* 匹配值
* 即预期结果
*/
private Object expectedResult;
/**
* 组内校验
*/
private Boolean arrayVerification;
/**
* 子对象
*/
private List<MsDocumentAssertionElement> children;
}

View File

@ -0,0 +1,15 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
import java.util.List;
@Data
public class MsJSONPathAssertion {
/**
* 断言列表
*/
private List<MsJSONPathAssertionItem> assertions;
}

View File

@ -0,0 +1,17 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@Data
public class MsJSONPathAssertionItem extends MsBodyAssertionItem {
private String expression;
private String condition;
private String expectedValue;
public boolean isValid() {
return StringUtils.isNotBlank(expression) && StringUtils.isNotBlank(condition) && StringUtils.isNotBlank(expectedValue);
}
}

View File

@ -0,0 +1,13 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
import java.util.List;
@Data
public class MsRegexAssertion {
/**
* 断言列表
*/
private List<MsRegexAssertionItem> assertions;
}

View File

@ -0,0 +1,13 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@Data
public class MsRegexAssertionItem extends MsBodyAssertionItem {
private String expression;
public boolean isValid() {
return StringUtils.isNotBlank(expression);
}
}

View File

@ -0,0 +1,30 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
import java.util.List;
@Data
public class MsXPathAssertion {
/**
* 响应内容格式
* xml 或者 html
*/
private String responseFormat;
/**
* xpath断言
*/
private List<MsXPathAssertionItem> assertions;
public enum ResponseFormat {
/**
* XML
*/
XML,
/**
* HTML
*/
HTML
}
}

View File

@ -0,0 +1,15 @@
package io.metersphere.project.dto.environment.assertion.body;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@Data
public class MsXPathAssertionItem extends MsBodyAssertionItem {
private String expression;
private String expectedValue;
public boolean isValid() {
return StringUtils.isNotBlank(expression) && StringUtils.isNotBlank(expectedValue);
}
}

View File

@ -1,20 +0,0 @@
package io.metersphere.project.dto.environment.assertions;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class EnvAssertionDuration extends EnvAssertionType {
@Schema(description = "响应时间")
private long value;
public EnvAssertionDuration() {
setType(DURATION);
}
public boolean isValid() {
return value > 0 && isEnable();
}
}

View File

@ -1,33 +0,0 @@
package io.metersphere.project.dto.environment.assertions;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
@Data
public class EnvAssertionJSR223 extends EnvAssertionType {
@Schema(description = "变量名")
private String variable;
@Schema(description = "操作符")
private String operator;
@Schema(description = "")
private String value;
@Schema(description = "脚本名称")
private String name;
@Schema(description = "脚本内容")
private String script;
@Schema(description = "脚本语言")
private String scriptLanguage;
@Schema(description = "是否启用jsr223")
private Boolean jsrEnable;
public EnvAssertionJSR223() {
setType(JSR223);
}
public boolean isValid() {
return StringUtils.isNotBlank(script) && StringUtils.isNotBlank(scriptLanguage) && isEnable();
}
}

View File

@ -1,27 +0,0 @@
package io.metersphere.project.dto.environment.assertions;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
@Data
public class EnvAssertionJsonPath extends EnvAssertionType {
@Schema(description = "期望值")
private String expect;
@Schema(description = "表达式")
private String expression;
@Schema(description = "描述")
private String description;
@Schema(description = "option 包含/不包含/正则/等于/不等于/大于/小于")
private String option = "REGEX";
public EnvAssertionJsonPath() {
setType(JSON_PATH);
}
public boolean isValid() {
return StringUtils.isNotBlank(expression) && isEnable();
}
}

View File

@ -1,27 +0,0 @@
package io.metersphere.project.dto.environment.assertions;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
@Data
public class EnvAssertionRegex extends EnvAssertionType {
@Schema(description = "断言对象 Response Headers/Response Code/Response Data")
private String subject;
@Schema(description = "表达式")
private String expression;
@Schema(description = "描述")
private String description;
@Schema(description = "忽略状态")
private Boolean assumeSuccess = false;
public EnvAssertionRegex() {
setType(EnvAssertionType.REGEX);
}
public boolean isValid() {
return StringUtils.isNotBlank(subject) && StringUtils.isNotBlank(expression) && isEnable();
}
}

View File

@ -1,18 +0,0 @@
package io.metersphere.project.dto.environment.assertions;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class EnvAssertionType {
public final static String REGEX = "Regex";
public final static String DURATION = "Duration";
public final static String JSON_PATH = "JSONPath";
public final static String JSR223 = "JSR223";
public final static String TEXT = "Text";
public final static String XPATH2 = "XPath2";
@Schema(description = "是否启用")
private boolean enable = true;
private String type;
}

View File

@ -1,21 +0,0 @@
package io.metersphere.project.dto.environment.assertions;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
@Data
public class EnvAssertionXPath extends EnvAssertionType {
@Schema(description = "表达式")
private String expression;
public EnvAssertionXPath() {
setType(XPATH2);
}
public boolean isValid() {
return StringUtils.isNotBlank(expression) && isEnable();
}
}

View File

@ -1,32 +0,0 @@
package io.metersphere.project.dto.environment.assertions;
import io.metersphere.project.dto.environment.assertions.document.MsAssertionDocument;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class EnvironmentAssertions {
@Schema(description = "接口测试")
private Boolean apiTest = true;
@Schema(description = "UI测试")
private Boolean uiTest = false;
@Schema(description = "xpath类型 xml/html")
private String xpathType;
@Schema(description = "正则断言")
private List<EnvAssertionRegex> regex;
@Schema(description = "jsonPath断言")
private List<EnvAssertionJsonPath> jsonPath;
@Schema(description = "jsr223断言")
private List<EnvAssertionJSR223> jsr223;
@Schema(description = "xpath断言")
private List<EnvAssertionXPath> xpath;
@Schema(description = "响应时间断言")
private EnvAssertionDuration duration;
@Schema(description = "文档断言")
private MsAssertionDocument document;
}

View File

@ -1,25 +0,0 @@
package io.metersphere.project.dto.environment.assertions.document;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class Document {
@Schema(description = "JSON跟随API 这里的是id")
private String jsonFollowAPI;
@Schema(description = "XML跟随API")
private String xmlFollowAPI;
@Schema(description = "JSON内容")
private List<DocumentElement> json;
@Schema(description = "XML内容")
private List<DocumentElement> xml;
@Schema(description = "是否包含")
private Boolean include = false;
@Schema(description = "是否包含类型")
private Boolean typeVerification = false;
}

View File

@ -1,36 +0,0 @@
package io.metersphere.project.dto.environment.assertions.document;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class DocumentElement {
@Schema(description = "id")
private String id;
@Schema(description = "名称")
private String name;
@Schema(description = "包含")
private Boolean include = false;
@Schema(description = "状态")
private String status;
@Schema(description = "类型校验")
private boolean typeVerification;
@Schema(description = "类型 object/array/string/number/boolean/integer")
private String type;
@Schema(description = "组id")
private String groupId;
@Schema(description = "行数")
private int rowspan;
@Schema(description = "校验组内元素")
private boolean arrayVerification;
@Schema(description = "内容校验 none/value_eq/value_not_eq/value_in/length_eq/length_not_eq/length_gt/length_lt/regular")
private String contentVerification;
@Schema(description = "预期结果")
private Object expectedOutcome;
@Schema(description = "子级")
private List<DocumentElement> children;
}

View File

@ -1,14 +0,0 @@
package io.metersphere.project.dto.environment.assertions.document;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class MsAssertionDocument {
@Schema(description = "是否启用")
private Boolean enable = true;
@Schema(description = "断言类型 JSON/XML")
private String type;
@Schema(description = "数据")
private Document data;
}

View File

@ -2,6 +2,7 @@ package io.metersphere.project.dto.environment.http;
import io.metersphere.project.dto.environment.KeyValue;
import io.metersphere.project.dto.environment.KeyValueEnableParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -24,7 +25,7 @@ public class HttpConfig implements Serializable {
@Schema(description = "启用条件为MODULE时需要模块的id")
private List<String> moduleIds;
@Schema(description = "请求头")
private List<KeyValue> headers;
private List<KeyValueEnableParam> headers;
@Schema(description = "浏览器 选项为chrome/firefox")
private String browser;
private String description;
@ -33,7 +34,7 @@ public class HttpConfig implements Serializable {
private static final long serialVersionUID = 1L;
public HttpConfig() {
this.headers = List.of(new KeyValue());
this.headers = List.of(new KeyValueEnableParam());
}
}

View File

@ -0,0 +1,17 @@
package io.metersphere.project.dto.environment.processors;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class ApiScript {
@Schema(description = "测试计划级 包括脚本和sql")
private List<MsProcessor> planProcessors;
@Schema(description = "场景级 包括脚本和sql")
private List<MsProcessor> scenarioProcessors;
@Schema(description = "步骤级 包括脚本和sql 脚本是脚本前和脚本后")
private List<MsProcessor> stepProcessors;
}

View File

@ -0,0 +1,24 @@
package io.metersphere.project.dto.environment.processors;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "processorType")
@JsonSubTypes({
@JsonSubTypes.Type(value = ScriptProcessor.class),
@JsonSubTypes.Type(value = SQLProcessor.class),
@JsonSubTypes.Type(value = ScenarioScript.class),
@JsonSubTypes.Type(value = StepScript.class),
})
public abstract class MsProcessor {
/**
* 名称
*/
private String name;
/**
* 是否启用
*/
private Boolean enable = true;
}

View File

@ -0,0 +1,45 @@
package io.metersphere.project.dto.environment.processors;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.project.dto.environment.KeyValueEnableParam;
import io.metersphere.project.dto.environment.KeyValueParam;
import lombok.Data;
import java.util.List;
@Data
@JsonTypeName("ENV_SQL")
public class SQLProcessor extends MsProcessor {
/**
* 脚本内容
*/
private String script;
/**
* 超时时间
*/
private long queryTimeout;
/**
* 存储结果
*/
private String resultVariable;
/**
* 按列存储
*/
private String variableNames;
/**
* 变量列表
*/
private List<KeyValueEnableParam> variables;
/**
* 环境ID
*/
private String environmentId;
/**
* 数据源ID
*/
private String dataSourceId;
/**
* 提取参数
*/
private List<KeyValueParam> extractParams;
}

View File

@ -0,0 +1,15 @@
package io.metersphere.project.dto.environment.processors;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@JsonTypeName("SCENARIO_SCRIPT")
public class ScenarioScript extends ScriptProcessor {
@Schema(description = "关联场景结果 true: 是/false: 否")
private Boolean associateScenarioResults = false;
}

View File

@ -0,0 +1,52 @@
package io.metersphere.project.dto.environment.processors;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.metersphere.project.dto.environment.KeyValueParam;
import lombok.Data;
import java.util.List;
@Data
@JsonTypeName("ENV_SCRIPT")
public class ScriptProcessor extends MsProcessor {
/**
* 脚本内容
*/
private String script;
/**
* 脚本语言
*
* @see ScriptLanguageType
*/
private String scriptLanguage;
/**
* 是否启用公共脚本
*/
private Boolean enableCommonScript = false;
/**
* 脚本ID
*/
private String scriptId;
/**
* 公共脚本入参
*/
private List<KeyValueParam> params;
public enum ScriptLanguageType {
BEANSHELL("beanshell"),
BEANSHELL_JSR233("beanshell-JSR233"),
GROOVY("groovy"),
JAVASCRIPT("javascript"),
PYTHON("python");
private String value;
ScriptLanguageType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}

View File

@ -0,0 +1,17 @@
package io.metersphere.project.dto.environment.processors;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@JsonTypeName("STEP_SCRIPT")
public class StepScript extends ScriptProcessor {
@Schema(description = "忽略请求")
private List<String> filterRequestScript;
@Schema(description = "脚本执行顺序 true:先执行 false:后执行")
private Boolean scriptExecBefore = true;
}

View File

@ -1,14 +1,14 @@
package io.metersphere.project.dto.environment.script.post;
package io.metersphere.project.dto.environment.processors.post;
import io.metersphere.project.dto.environment.script.ScriptContent;
import io.metersphere.project.dto.environment.processors.ApiScript;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class EnvironmentPostScript {
@Schema(description = "接口测试")
private ScriptContent.ApiScript apiPostScript;
private ApiScript apiPostScript;
@Schema(description = "UI测试")
private UiPostScript uiPostScript;

View File

@ -1,4 +1,4 @@
package io.metersphere.project.dto.environment.script.post;
package io.metersphere.project.dto.environment.processors.post;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,14 +1,14 @@
package io.metersphere.project.dto.environment.script.pre;
package io.metersphere.project.dto.environment.processors.pre;
import io.metersphere.project.dto.environment.script.ScriptContent;
import io.metersphere.project.dto.environment.processors.ApiScript;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class EnvironmentPreScript {
@Schema(description = "接口测试")
private ScriptContent.ApiScript apiPreScript;
private ApiScript apiPreScript;
@Schema(description = "UI测试")
private UiPreScript uiPreScript;

View File

@ -1,4 +1,4 @@
package io.metersphere.project.dto.environment.script.pre;
package io.metersphere.project.dto.environment.processors.pre;
import io.swagger.v3.oas.annotations.media.Schema;

View File

@ -1,50 +0,0 @@
package io.metersphere.project.dto.environment.script;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
public class ScriptContent {
@Schema(description = "脚本内容")
private String script;
@Schema(description = "脚本语言")
private String scriptLanguage;
@Schema(description = "是否是jsr223")
private Boolean jsrEnable;
@Data
@EqualsAndHashCode(callSuper = true)
public static class ScenarioScript extends ScriptContent {
@Schema(description = "关联场景结果 true: 是/false: 否")
private Boolean associateScenarioResults = false;
}
@Data
@EqualsAndHashCode(callSuper = true)
public static class StepScript extends ScriptContent {
@Schema(description = "忽略请求")
private List<String> filterRequestScript;
@Schema(description = "脚本执行顺序 true:先执行 false:后执行")
private Boolean scriptExecBefore = true;
@Schema(description = "脚本内容")
private ScriptContent scriptContent;
}
@Data
public static class ApiScript {
@Schema(description = "测试计划级")
private ScriptContent envJSR223Script;
@Schema(description = "场景级")
private ScenarioScript scenarioJSR223Script;
@Schema(description = "步骤级 ")
private List<StepScript> stepJSR223Script;
}
}

View File

@ -8,6 +8,7 @@ import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.util.List;
@Data
public class CommonVariables implements Serializable {
@ -25,6 +26,8 @@ public class CommonVariables implements Serializable {
private Boolean enable = true;
@Schema(description = "描述")
private String description;
@Schema(description = "标签")
private List<String> tags;
@JsonIgnore

View File

@ -6,11 +6,15 @@ import io.metersphere.project.dto.environment.*;
import io.metersphere.project.dto.environment.datasource.DataSource;
import io.metersphere.project.mapper.ExtEnvironmentMapper;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.utils.FileDownloadUtils;
import io.metersphere.sdk.constants.DefaultRepositoryDir;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.domain.*;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.sdk.domain.EnvironmentBlob;
import io.metersphere.sdk.domain.EnvironmentBlobExample;
import io.metersphere.sdk.domain.EnvironmentExample;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.file.FileRequest;
import io.metersphere.sdk.file.MinioRepository;
import io.metersphere.sdk.mapper.EnvironmentBlobMapper;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.sdk.mapper.ProjectParametersMapper;
@ -21,8 +25,7 @@ import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.sdk.BaseSystemConfigDTO;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.sdk.file.FileRequest;
import io.metersphere.sdk.file.MinioRepository;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.metersphere.system.log.constants.OperationLogModule;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.log.dto.LogDTO;
@ -187,51 +190,29 @@ public class EnvironmentService {
return (pos == null ? 0 : pos) + ORDER_STEP;
}
public ResponseEntity<byte[]> exportZip(EnvironmentExportRequest request) {
public ResponseEntity<byte[]> exportJson(TableBatchProcessDTO request, String projectId) {
try {
byte[] bytes = this.download(request);
Project project = projectMapper.selectByPrimaryKey(projectId);
List<EnvironmentRequest> environmentList = this.exportEnv(request, projectId);
String fileName = null;
if (CollectionUtils.isNotEmpty(environmentList)) {
if (environmentList.size() == 1) {
fileName = StringUtils.join(project.getName(), "_", environmentList.get(0).getName(), ".json");
} else {
fileName = StringUtils.join(project.getName(), "_", Translator.get("env_info_all"));
}
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "files.zip")
.body(bytes);
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName)
.body(JSON.toJSONString(environmentList).getBytes());
} catch (Exception e) {
return ResponseEntity.status(509).body(e.getMessage().getBytes());
}
}
public byte[] download(EnvironmentExportRequest request) {
Map<String, byte[]> files = new LinkedHashMap<>();
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
if (BooleanUtils.isTrue(request.getGlobalParam())) {
//查询全局参数
EnvironmentExportDTO environmentExportDTO = new EnvironmentExportDTO();
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(request.getProjectId());
List<ProjectParameters> projectParameters = projectParametersMapper.selectByExampleWithBLOBs(projectParametersExample);
if (CollectionUtils.isNotEmpty(projectParameters)) {
environmentExportDTO.setGlobalParam(true);
environmentExportDTO.setData(new String(projectParameters.get(0).getParameters()));
files.put(StringUtils.join(project.getName(), "_", Translator.get("global_params")), JSON.toJSONString(environmentExportDTO).getBytes());
}
}
if (BooleanUtils.isTrue(request.getEnvironment())) {
EnvironmentExportDTO environmentExportDTO = new EnvironmentExportDTO();
List<EnvironmentRequest> environmentList = this.exportEnv(request);
if (CollectionUtils.isNotEmpty(environmentList)) {
environmentExportDTO.setEnvironment(true);
environmentExportDTO.setData(JSON.toJSONString(environmentList));
if (environmentList.size() == 1) {
files.put(StringUtils.join(project.getName(), "_", environmentList.get(0).getName(), ".json"), JSON.toJSONString(environmentList.get(0)).getBytes());
} else {
files.put(StringUtils.join(project.getName(), "_", Translator.get("env_info_all")), JSON.toJSONString(environmentExportDTO).getBytes());
}
}
}
return FileDownloadUtils.listFileBytesToZip(files);
}
public List<EnvironmentRequest> exportEnv(EnvironmentExportRequest environmentExportRequest) {
List<String> environmentIds = this.getEnvironmentIds(environmentExportRequest);
public List<EnvironmentRequest> exportEnv(TableBatchProcessDTO request, String projectId) {
List<String> environmentIds = this.getEnvironmentIds(request, projectId);
// 查询环境
EnvironmentExample environmentExample = new EnvironmentExample();
environmentExample.createCriteria().andIdIn(environmentIds);
@ -271,9 +252,9 @@ public class EnvironmentService {
}
}
private List<String> getEnvironmentIds(EnvironmentExportRequest request) {
private List<String> getEnvironmentIds(TableBatchProcessDTO request, String projectId) {
if (request.isSelectAll()) {
List<Environment> environments = extEnvironmentMapper.selectByKeyword(request.getCondition().getKeyword(), true, request.getProjectId());
List<Environment> environments = extEnvironmentMapper.selectByKeyword(request.getCondition().getKeyword(), true, projectId);
List<String> environmentIds = environments.stream().map(Environment::getId).collect(Collectors.toList());
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(request.getExcludeIds())) {
environmentIds.removeAll(request.getExcludeIds());
@ -318,82 +299,55 @@ public class EnvironmentService {
// 读取文件内容
String content = new String(inputStream.readAllBytes());
inputStream.close();
//参数是一个对象
EnvironmentExportDTO environmentExportDTO = JSON.parseObject(content, EnvironmentExportDTO.class);
if (environmentExportDTO != null) {
if (BooleanUtils.isTrue(environmentExportDTO.getGlobalParam())) {
String data = environmentExportDTO.getData();
//解析出来的参数是一个对象
if (BooleanUtils.isTrue(request.getCover())) {
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(currentProjectId);
if (projectParametersMapper.countByExample(projectParametersExample) > 0) {
projectParametersMapper.deleteByExample(projectParametersExample);
}
ProjectParameters projectParameters = new ProjectParameters();
projectParameters.setId(IDGenerator.nextStr());
projectParameters.setProjectId(currentProjectId);
projectParameters.setCreateUser(userId);
projectParameters.setUpdateUser(userId);
projectParameters.setCreateTime(System.currentTimeMillis());
projectParameters.setUpdateTime(System.currentTimeMillis());
projectParameters.setParameters(data.getBytes());
projectParametersMapper.insert(projectParameters);
}
}
if (BooleanUtils.isTrue(environmentExportDTO.getEnvironment())) {
// 拿到的参数是一个list
List<EnvironmentRequest> environmentRequests = JSON.parseArray(environmentExportDTO.getData(), EnvironmentRequest.class);
if (CollectionUtils.isNotEmpty(environmentRequests)) {
List<Environment> environments = new ArrayList<>();
List<EnvironmentBlob> environmentBlobs = new ArrayList<>();
List<LogDTO> logDos = new ArrayList<>();
Project project = projectMapper.selectByPrimaryKey(currentProjectId);
environmentRequests.forEach(environmentRequest -> {
Environment environment = new Environment();
environment.setId(IDGenerator.nextStr());
environment.setCreateUser(userId);
environment.setName(environmentRequest.getName());
environment.setProjectId(currentProjectId);
environment.setUpdateUser(userId);
environment.setUpdateTime(System.currentTimeMillis());
environment.setMock(false);
environment.setPos(getNextOrder(currentProjectId));
Environment exitsEnv = getExitsEnv(environment);
if (exitsEnv != null && BooleanUtils.isTrue(request.getCover())) {
environmentMapper.deleteByPrimaryKey(exitsEnv.getId());
environmentBlobMapper.deleteByPrimaryKey(exitsEnv.getId());
} else if (exitsEnv != null && BooleanUtils.isFalse(request.getCover())) {
return;
}
environment.setCreateTime(System.currentTimeMillis());
environment.setProjectId(currentProjectId);
environments.add(environment);
EnvironmentBlob environmentBlob = new EnvironmentBlob();
environmentBlob.setId(environment.getId());
environmentBlob.setConfig(JSON.toJSONBytes(environmentRequest.getConfig()));
environmentBlobs.add(environmentBlob);
LogDTO logDTO = new LogDTO(
currentProjectId,
project.getOrganizationId(),
environment.getId(),
userId,
OperationLogType.ADD.name(),
OperationLogModule.PROJECT_ENVIRONMENT_SETTING,
environment.getName());
logDTO.setMethod(HttpMethodConstants.POST.name());
logDTO.setOriginalValue(JSON.toJSONBytes(environmentRequest.getConfig()));
logDTO.setPath(PATH);
logDos.add(logDTO);
});
if (CollectionUtils.isNotEmpty(environments)
&& CollectionUtils.isNotEmpty(environmentBlobs)
&& CollectionUtils.isNotEmpty(logDos)) {
environmentMapper.batchInsert(environments);
environmentBlobMapper.batchInsert(environmentBlobs);
operationLogService.batchAdd(logDos);
}
List<EnvironmentRequest> environmentRequests = JSON.parseArray(content, EnvironmentRequest.class);
if (CollectionUtils.isNotEmpty(environmentRequests)) {
List<Environment> environments = new ArrayList<>();
List<EnvironmentBlob> environmentBlobs = new ArrayList<>();
List<LogDTO> logDos = new ArrayList<>();
Project project = projectMapper.selectByPrimaryKey(currentProjectId);
environmentRequests.forEach(environmentRequest -> {
Environment environment = new Environment();
environment.setId(IDGenerator.nextStr());
environment.setCreateUser(userId);
environment.setName(environmentRequest.getName());
environment.setProjectId(currentProjectId);
environment.setUpdateUser(userId);
environment.setUpdateTime(System.currentTimeMillis());
environment.setMock(false);
environment.setPos(getNextOrder(currentProjectId));
Environment exitsEnv = getExitsEnv(environment);
if (exitsEnv != null && BooleanUtils.isTrue(request.getCover())) {
environmentMapper.deleteByPrimaryKey(exitsEnv.getId());
environmentBlobMapper.deleteByPrimaryKey(exitsEnv.getId());
} else if (exitsEnv != null && BooleanUtils.isFalse(request.getCover())) {
return;
}
environment.setCreateTime(System.currentTimeMillis());
environment.setProjectId(currentProjectId);
environments.add(environment);
EnvironmentBlob environmentBlob = new EnvironmentBlob();
environmentBlob.setId(environment.getId());
environmentBlob.setConfig(JSON.toJSONBytes(environmentRequest.getConfig()));
environmentBlobs.add(environmentBlob);
LogDTO logDTO = new LogDTO(
currentProjectId,
project.getOrganizationId(),
environment.getId(),
userId,
OperationLogType.ADD.name(),
OperationLogModule.PROJECT_ENVIRONMENT_SETTING,
environment.getName());
logDTO.setMethod(HttpMethodConstants.POST.name());
logDTO.setOriginalValue(JSON.toJSONBytes(environmentRequest.getConfig()));
logDTO.setPath(PATH);
logDos.add(logDTO);
});
if (CollectionUtils.isNotEmpty(environments)
&& CollectionUtils.isNotEmpty(environmentBlobs)
&& CollectionUtils.isNotEmpty(logDos)) {
environmentMapper.batchInsert(environments);
environmentBlobMapper.batchInsert(environmentBlobs);
operationLogService.batchAdd(logDos);
}
}
} catch (Exception e) {

View File

@ -1,21 +1,29 @@
package io.metersphere.project.service;
import io.metersphere.project.domain.Project;
import io.metersphere.project.dto.environment.GlobalParams;
import io.metersphere.project.dto.environment.GlobalParamsDTO;
import io.metersphere.project.dto.environment.GlobalParamsRequest;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.domain.ProjectParameters;
import io.metersphere.sdk.domain.ProjectParametersExample;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.mapper.ProjectParametersMapper;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.List;
@ -28,7 +36,7 @@ public class GlobalParamsService {
@Resource
private ProjectMapper projectMapper;
public GlobalParamsRequest add(GlobalParamsRequest globalParamsRequest, String userId) {
public ProjectParameters add(GlobalParamsRequest globalParamsRequest, String userId) {
ProjectParameters projectParameters = new ProjectParameters();
projectParameters.setProjectId(globalParamsRequest.getProjectId());
checkExist(globalParamsRequest.getProjectId());
@ -41,10 +49,10 @@ public class GlobalParamsService {
projectParameters.setParameters(JSON.toJSONBytes(globalParamsRequest.getGlobalParams()));
projectParametersMapper.insert(projectParameters);
globalParamsRequest.setId(projectParameters.getId());
return globalParamsRequest;
return projectParameters;
}
public GlobalParamsRequest update(GlobalParamsRequest globalParamsRequest, String userId) {
public ProjectParameters update(GlobalParamsRequest globalParamsRequest, String userId) {
ProjectParameters projectParameters = new ProjectParameters();
projectParameters.setProjectId(globalParamsRequest.getProjectId());
checkDataExist(globalParamsRequest.getProjectId());
@ -54,7 +62,7 @@ public class GlobalParamsService {
projectParameters.setUpdateTime(System.currentTimeMillis());
projectParameters.setParameters(JSON.toJSONBytes(globalParamsRequest.getGlobalParams()));
projectParametersMapper.updateByPrimaryKeySelective(projectParameters);
return globalParamsRequest;
return projectParameters;
}
private void checkDataExist(String projectId) {
@ -66,16 +74,16 @@ public class GlobalParamsService {
}
}
public GlobalParamsRequest get(String projectId) {
public GlobalParamsDTO get(String projectId) {
ProjectParametersExample example = new ProjectParametersExample();
example.createCriteria().andProjectIdEqualTo(projectId);
List<ProjectParameters> projectParametersList = projectParametersMapper.selectByExampleWithBLOBs(example);
if (CollectionUtils.isNotEmpty(projectParametersList)) {
GlobalParamsRequest globalParamsRequest = new GlobalParamsRequest();
globalParamsRequest.setProjectId(projectId);
globalParamsRequest.setId(projectParametersList.get(0).getId());
globalParamsRequest.setGlobalParams(JSON.parseObject(new String(projectParametersList.get(0).getParameters()), GlobalParams.class));
return globalParamsRequest;
GlobalParamsDTO globalParamsDTO = new GlobalParamsDTO();
globalParamsDTO.setProjectId(projectId);
globalParamsDTO.setId(projectParametersList.get(0).getId());
globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParametersList.get(0).getParameters()), GlobalParams.class));
return globalParamsDTO;
} else {
return null;
}
@ -96,4 +104,61 @@ public class GlobalParamsService {
throw new MSException(Translator.get("project_is_not_exist"));
}
}
public ResponseEntity<byte[]> exportJson(String projectId) {
try {
Project project = projectMapper.selectByPrimaryKey(projectId);
//查询全局参数
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(projectId);
List<ProjectParameters> projectParameters = projectParametersMapper.selectByExampleWithBLOBs(projectParametersExample);
byte[] bytes = new byte[0];
if (CollectionUtils.isNotEmpty(projectParameters)) {
GlobalParamsDTO globalParamsDTO = new GlobalParamsDTO();
globalParamsDTO.setProjectId(projectId);
globalParamsDTO.setId(projectParameters.get(0).getId());
globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParameters.get(0).getParameters()), GlobalParams.class));
bytes = JSON.toJSONString(globalParamsDTO).getBytes();
} else {
throw new MSException(Translator.get("global_parameters_is_not_exist"));
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + StringUtils.join(project.getName(), "_", Translator.get("global_params")))
.body(bytes);
} catch (Exception e) {
return ResponseEntity.status(509).body(e.getMessage().getBytes());
}
}
public void importData(MultipartFile file, String userId, String currentProjectId) {
if (file != null) {
try {
InputStream inputStream = file.getInputStream();
// 读取文件内容
String content = new String(inputStream.readAllBytes());
inputStream.close();
//参数是一个对象
GlobalParamsDTO globalParamsDTO = JSON.parseObject(content, GlobalParamsDTO.class);
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(currentProjectId);
if (projectParametersMapper.countByExample(projectParametersExample) > 0) {
projectParametersMapper.deleteByExample(projectParametersExample);
}
ProjectParameters projectParameters = new ProjectParameters();
projectParameters.setId(IDGenerator.nextStr());
projectParameters.setProjectId(currentProjectId);
projectParameters.setCreateUser(userId);
projectParameters.setUpdateUser(userId);
projectParameters.setCreateTime(System.currentTimeMillis());
projectParameters.setUpdateTime(System.currentTimeMillis());
projectParameters.setParameters(JSON.toJSONBytes(globalParamsDTO.getGlobalParams()));
projectParametersMapper.insert(projectParameters);
} catch (Exception e) {
LogUtils.error("获取文件输入流异常", e);
throw new RuntimeException("获取文件输入流异常", e);
}
}
}
}

View File

@ -1,32 +1,30 @@
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.assertion.*;
import io.metersphere.project.dto.environment.assertion.body.*;
import io.metersphere.project.dto.environment.auth.AuthConfig;
import io.metersphere.project.dto.environment.common.CommonParams;
import io.metersphere.project.dto.environment.datasource.DataSource;
import io.metersphere.project.dto.environment.host.Host;
import io.metersphere.project.dto.environment.host.HostConfig;
import io.metersphere.project.dto.environment.http.HttpConfig;
import io.metersphere.project.dto.environment.script.ScriptContent;
import io.metersphere.project.dto.environment.script.post.EnvironmentPostScript;
import io.metersphere.project.dto.environment.script.post.UiPostScript;
import io.metersphere.project.dto.environment.script.pre.EnvironmentPreScript;
import io.metersphere.project.dto.environment.script.pre.UiPreScript;
import io.metersphere.project.dto.environment.processors.*;
import io.metersphere.project.dto.environment.processors.post.EnvironmentPostScript;
import io.metersphere.project.dto.environment.processors.post.UiPostScript;
import io.metersphere.project.dto.environment.processors.pre.EnvironmentPreScript;
import io.metersphere.project.dto.environment.processors.pre.UiPreScript;
import io.metersphere.project.dto.environment.ssl.KeyStoreConfig;
import io.metersphere.project.dto.environment.ssl.KeyStoreEntry;
import io.metersphere.project.dto.environment.ssl.KeyStoreFile;
import io.metersphere.project.dto.environment.variables.CommonVariables;
import io.metersphere.sdk.constants.DefaultRepositoryDir;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.constants.VariableTypeConstants;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.sdk.domain.EnvironmentBlob;
import io.metersphere.sdk.domain.EnvironmentExample;
import io.metersphere.sdk.domain.ProjectParametersExample;
import io.metersphere.sdk.file.FileRequest;
import io.metersphere.sdk.file.MinioRepository;
import io.metersphere.sdk.mapper.EnvironmentBlobMapper;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.sdk.mapper.ProjectParametersMapper;
@ -36,8 +34,7 @@ import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.sdk.file.FileRequest;
import io.metersphere.sdk.file.MinioRepository;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.metersphere.system.log.constants.OperationLogType;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
@ -61,6 +58,7 @@ import org.springframework.util.MultiValueMap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -71,7 +69,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class EnvironmentControllerTests extends BaseTest {
@ -214,9 +212,9 @@ public class EnvironmentControllerTests extends BaseTest {
private List<HttpConfig> createHttpConfig() {
List<HttpConfig> httpConfigs = new ArrayList<>();
HttpConfig httpConfig = new HttpConfig();
List<KeyValue> headers = new ArrayList<>();
KeyValue keyValue = new KeyValue();
keyValue.setName("key");
List<KeyValueEnableParam> headers = new ArrayList<>();
KeyValueEnableParam keyValue = new KeyValueEnableParam();
keyValue.setKey("key");
keyValue.setValue("value");
headers.add(keyValue);
httpConfig.setHeaders(headers);
@ -307,20 +305,31 @@ public class EnvironmentControllerTests extends BaseTest {
return keyStoreConfig;
}
private ScriptContent.ApiScript createApiScript() {
ScriptContent.ApiScript apiScript = new ScriptContent.ApiScript();
ScriptContent scriptContent = new ScriptContent();
scriptContent.setScript("script");
apiScript.setEnvJSR223Script(scriptContent);
ScriptContent.ScenarioScript scenarioScript = new ScriptContent.ScenarioScript();
scenarioScript.setAssociateScenarioResults(true);
scenarioScript.setScript("scenarioPostScript");
apiScript.setScenarioJSR223Script(scenarioScript);
ScriptContent.StepScript stepPostScript = new ScriptContent.StepScript();
stepPostScript.setScriptExecBefore(true);
stepPostScript.setScriptContent(scriptContent);
stepPostScript.setFilterRequestScript(new ArrayList<>());
apiScript.setStepJSR223Script(List.of(stepPostScript));
private ApiScript createApiScript() {
ApiScript apiScript = new ApiScript();
ScriptProcessor scriptProcessor = new ScriptProcessor();
scriptProcessor.setScript("script");
scriptProcessor.setName("测试计划级别脚本");
SQLProcessor sqlProcessor = new SQLProcessor();
sqlProcessor.setEnvironmentId("environmentId");
sqlProcessor.setDataSourceId("dataSourceId");
sqlProcessor.setQueryTimeout(1000L);
apiScript.setPlanProcessors(List.of(scriptProcessor, sqlProcessor));
ScenarioScript scenarioScript = new ScenarioScript();
scenarioScript.setScript("script");
scenarioScript.setName("场景级别脚本");
apiScript.setScenarioProcessors(List.of(scenarioScript, sqlProcessor));
StepScript stepScript = new StepScript();
stepScript.setScript("script");
stepScript.setName("步骤级别前置脚本前");
stepScript.setScriptExecBefore(true);
stepScript.setFilterRequestScript(List.of("HTTP"));
StepScript stepScriptAfter = new StepScript();
stepScriptAfter.setScript("script");
stepScriptAfter.setName("步骤级别前置脚本后");
stepScriptAfter.setScriptExecBefore(false);
stepScriptAfter.setFilterRequestScript(List.of("HTTP"));
apiScript.setStepProcessors(List.of(stepScript, sqlProcessor, stepScriptAfter));
return apiScript;
}
@ -343,17 +352,85 @@ public class EnvironmentControllerTests extends BaseTest {
return uiPostScript;
}
private EnvironmentAssertions createAssertions() {
EnvironmentAssertions assertions = new EnvironmentAssertions();
assertions.setApiTest(true);
List<EnvAssertionRegex> regex = new ArrayList<>();
assertions.setRegex(regex);
List<EnvAssertionJsonPath> jsonPath = new ArrayList<>();
assertions.setJsonPath(jsonPath);
List<EnvAssertionJSR223> jsr223 = new ArrayList<>();
assertions.setJsr223(jsr223);
List<EnvAssertionXPath> xpath = new ArrayList<>();
assertions.setXpath(xpath);
public static List<MsAssertion> getGeneralAssertions() {
List<MsAssertion> assertions = new ArrayList<>();
MsResponseCodeAssertion responseCodeAssertion = new MsResponseCodeAssertion();
responseCodeAssertion.setCondition(MsAssertionCondition.EMPTY.name());
responseCodeAssertion.setExpectedValue("value");
responseCodeAssertion.setName("name");
assertions.add(responseCodeAssertion);
MsResponseHeaderAssertion responseHeaderAssertion = new MsResponseHeaderAssertion();
MsResponseHeaderAssertion.ResponseHeaderAssertionItem responseHeaderAssertionItem = new MsResponseHeaderAssertion.ResponseHeaderAssertionItem();
responseHeaderAssertionItem.setHeader("header");
responseHeaderAssertionItem.setExpectedValue("value");
responseHeaderAssertionItem.setCondition(MsAssertionCondition.EMPTY.name());
responseHeaderAssertion.setAssertions(List.of(responseHeaderAssertionItem));
assertions.add(responseHeaderAssertion);
MsResponseBodyAssertion regexResponseBodyAssertion = new MsResponseBodyAssertion();
regexResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.REGEX.name());
MsRegexAssertion regexAssertion = new MsRegexAssertion();
MsRegexAssertionItem msRegexAssertionItem = new MsRegexAssertionItem();
msRegexAssertionItem.setExpression("^test");
regexAssertion.setAssertions(List.of(msRegexAssertionItem));
regexResponseBodyAssertion.setRegexAssertion(regexAssertion);
assertions.add(regexResponseBodyAssertion);
MsResponseBodyAssertion documentResponseBodyAssertion = new MsResponseBodyAssertion();
documentResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.DOCUMENT.name());
MsDocumentAssertion msDocumentAssertion = new MsDocumentAssertion();
documentResponseBodyAssertion.setDocumentAssertion(msDocumentAssertion);
assertions.add(documentResponseBodyAssertion);
MsResponseBodyAssertion jsonPathResponseBodyAssertion = new MsResponseBodyAssertion();
jsonPathResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.JSON_PATH.name());
MsJSONPathAssertion msJSONPathAssertion = new MsJSONPathAssertion();
MsJSONPathAssertionItem msJSONPathAssertionItem = new MsJSONPathAssertionItem();
msJSONPathAssertionItem.setExpression("^test");
msJSONPathAssertionItem.setCondition(MsAssertionCondition.REGEX.name());
msJSONPathAssertionItem.setExpectedValue("expectedValue");
msJSONPathAssertion.setAssertions(List.of(msJSONPathAssertionItem));
jsonPathResponseBodyAssertion.setJsonPathAssertion(msJSONPathAssertion);
assertions.add(jsonPathResponseBodyAssertion);
MsResponseBodyAssertion xpathPathResponseBodyAssertion = new MsResponseBodyAssertion();
xpathPathResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.XPATH.name());
MsXPathAssertion xPathPathAssertion = new MsXPathAssertion();
xPathPathAssertion.setResponseFormat(MsXPathAssertion.ResponseFormat.XML.name());
MsXPathAssertionItem xPathAssertionItem = new MsXPathAssertionItem();
xPathAssertionItem.setExpression("^test");
xPathAssertionItem.setExpectedValue("expectedValue");
xPathPathAssertion.setAssertions(List.of(xPathAssertionItem));
xpathPathResponseBodyAssertion.setXpathAssertion(xPathPathAssertion);
assertions.add(xpathPathResponseBodyAssertion);
MsResponseTimeAssertion responseTimeAssertion = new MsResponseTimeAssertion();
responseTimeAssertion.setExpectedValue(1000L);
responseTimeAssertion.setEnable(true);
responseTimeAssertion.setName("aa");
assertions.add(responseTimeAssertion);
MsScriptAssertion scriptAssertion = new MsScriptAssertion();
scriptAssertion.setScriptId("1111");
scriptAssertion.setScript("1111");
scriptAssertion.setName("1111");
assertions.add(scriptAssertion);
MsVariableAssertion msVariableAssertion = new MsVariableAssertion();
MsVariableAssertion.VariableAssertionItem variableAssertionItem = new MsVariableAssertion.VariableAssertionItem();
variableAssertionItem.setCondition(MsAssertionCondition.GT.name());
variableAssertionItem.setExpectedValue("ev");
variableAssertionItem.setVariableName("vn");
msVariableAssertion.setVariableAssertionItems(List.of(variableAssertionItem));
assertions.add(msVariableAssertion);
return assertions;
}
private MsAssertionConfig createAssertions() {
MsAssertionConfig assertions = new MsAssertionConfig();
assertions.setAssertions(getGeneralAssertions());
return assertions;
}
@ -393,6 +470,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setCommonParams(createCommonParams());
request.setName("commonParams");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -418,6 +496,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setCommonVariables(createCommonVariables(1));
request.setName("commonVariables");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -443,6 +522,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setHttpConfig(createHttpConfig());
request.setName("httpConfig");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -468,6 +548,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setDataSources(createDataSources());
request.setName("dataSources");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -493,6 +574,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setHostConfig(crateHostConfig());
request.setName("hostConfig");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -518,6 +600,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setAuthConfig(createAuthConfig());
request.setName("authConfig");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -545,6 +628,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setAuthConfig(authConfig);
request.setName("sslConfig");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -570,6 +654,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setPreScript(createEnvironmentPreScript());
request.setName("preScript");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -595,6 +680,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setPostScript(createEnvironmentPostScript());
request.setName("postScript");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -621,6 +707,7 @@ public class EnvironmentControllerTests extends BaseTest {
envConfig.setAssertions(createAssertions());
request.setName("assertions");
request.setConfig(envConfig);
paramMap.clear();
paramMap.set("request", JSON.toJSONString(request));
mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap);
response = parseObjectFromMvcResult(mvcResult, Environment.class);
@ -788,7 +875,7 @@ public class EnvironmentControllerTests extends BaseTest {
// 测试500
dataSource.setDriver("com.mysql.cj.jdbc.Driver");
dataSource.setDbUrl("jdbc:mysql://");
this.requestPost(validate + "500", dataSource, ERROR_REQUEST_MATCHER);
this.requestPost(validate, dataSource, ERROR_REQUEST_MATCHER);
}
@Test
@ -903,10 +990,10 @@ public class EnvironmentControllerTests extends BaseTest {
List<Environment> environments = environmentMapper.selectByExample(example);
posRequest.setMoveId(environments.get(0).getId());
posRequest.setMoveMode("AFTER");
this.requestPostWithOkAndReturn(POS_URL, posRequest);
this.requestPostWithOkAndReturn(POS_URL, posRequest, DEFAULT_PROJECT_ID);
posRequest.setMoveMode("BEFORE");
this.requestPostWithOkAndReturn(POS_URL, posRequest);
this.requestPostWithOkAndReturn(POS_URL, posRequest, DEFAULT_PROJECT_ID);
}
@ -964,11 +1051,11 @@ public class EnvironmentControllerTests extends BaseTest {
Assertions.assertEquals(1, response.size());
environmentDTO.setProjectId(DEFAULT_PROJECT_ID);
//校验权限
requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, list , environmentDTO);
requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, list, environmentDTO);
//项目不存在 返回内容为[]
environmentDTO.setProjectId("ceshi");
mvcResult = this.responsePost(list ,environmentDTO);
mvcResult = this.responsePost(list, environmentDTO);
response = parseObjectFromMvcResult(mvcResult, List.class);
Assertions.assertEquals(0, response.size());
}
@ -1041,52 +1128,50 @@ public class EnvironmentControllerTests extends BaseTest {
@Order(14)
public void testExport() throws Exception {
//指定id
EnvironmentExportRequest environmentExportRequest = new EnvironmentExportRequest();
environmentExportRequest.setProjectId(DEFAULT_PROJECT_ID);
environmentExportRequest.setEnvironment(true);
environmentExportRequest.setSelectIds(List.of("environmentId1"));
MvcResult mvcResult = this.requestPostDownloadFile(exportEnv, null, environmentExportRequest);
TableBatchProcessDTO request = new TableBatchProcessDTO();
request.setSelectIds(List.of("environmentId1"));
MvcResult mvcResult = this.requestPostDownloadFile(exportEnv, null, request, DEFAULT_PROJECT_ID);
byte[] fileBytes = mvcResult.getResponse().getContentAsByteArray();
Assertions.assertNotNull(fileBytes);
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
if (projectParametersMapper.countByExample(projectParametersExample) == 0) {
//全局参数
GlobalParamsRequest request = new GlobalParamsRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
GlobalParams globalParams = new GlobalParams();
globalParams.setHeaders(getHeaders(1));
globalParams.setCommonVariables(getEnvVariables(1));
request.setGlobalParams(globalParams);
this.responsePost("/project/global/params/add", request);
}
//全选
environmentExportRequest.setGlobalParam(true);
environmentExportRequest.setSelectIds(List.of("environmentId1"));
environmentExportRequest.setSelectAll(true);
environmentExportRequest.setExcludeIds(List.of("environmentId1"));
MvcResult mvcResult1 = this.requestPostDownloadFile(exportEnv, null, environmentExportRequest);
request.setSelectIds(List.of("environmentId1"));
request.setSelectAll(true);
request.setExcludeIds(List.of("environmentId1"));
MvcResult mvcResult1 = this.requestPostDownloadFile(exportEnv, null, request, DEFAULT_PROJECT_ID);
byte[] fileBytes1 = mvcResult1.getResponse().getContentAsByteArray();
File file = new File("test.json");
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(fileBytes1);
fileOutputStream.close();
Assertions.assertNotNull(fileBytes1);
projectParametersMapper.deleteByExample(projectParametersExample);
environmentExportRequest.setSelectIds(List.of("不存在blob"));
environmentExportRequest.setSelectAll(false);
environmentExportRequest.setEnvironment(true);
mockMvc.perform(getPostRequestBuilder(exportEnv, environmentExportRequest))
request.setSelectIds(List.of("不存在blob"));
request.setSelectAll(false);
mockMvc.perform(getPostRequestBuilder(exportEnv, request, DEFAULT_PROJECT_ID))
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
.andExpect(ERROR_REQUEST_MATCHER);
}
protected MvcResult requestPostDownloadFile(String url, MediaType contentType, Object param) throws Exception {
protected MvcResult requestPostDownloadFile(String url, MediaType contentType, Object param, String projectId) throws Exception {
if (contentType == null) {
contentType = MediaType.APPLICATION_OCTET_STREAM;
}
return mockMvc.perform(getPostRequestBuilder(url, param))
return mockMvc.perform(getPostRequestBuilder(url, param, projectId))
.andExpect(content().contentType(contentType))
.andExpect(status().isOk()).andReturn();
}
protected MockHttpServletRequestBuilder getPostRequestBuilder(String url, Object param, Object... uriVariables) {
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post(getBasePath() + url);
return requestBuilder
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.header(SessionConstants.CURRENT_PROJECT, uriVariables)
.header(org.apache.http.HttpHeaders.ACCEPT_LANGUAGE, "zh-CN")
.content(JSON.toJSONString(param))
.contentType(MediaType.APPLICATION_JSON);
}
@Test
@Order(15)
public void testImport() throws Exception {
@ -1109,38 +1194,6 @@ public class EnvironmentControllerTests extends BaseTest {
paramMap.add("request", JSON.toJSONString(request));
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
//上传全局参数
ProjectParametersExample projectParametersExample = new ProjectParametersExample();
projectParametersExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
if (projectParametersMapper.countByExample(projectParametersExample) == 0) {
//全局参数
GlobalParamsRequest globalParamsRequest = new GlobalParamsRequest();
globalParamsRequest.setProjectId(DEFAULT_PROJECT_ID);
GlobalParams globalParams = new GlobalParams();
globalParams.setHeaders(getHeaders(1));
globalParams.setCommonVariables(getEnvVariables(1));
globalParamsRequest.setGlobalParams(globalParams);
this.responsePost("/project/global/params/add", globalParamsRequest);
}
inputStream = new FileInputStream(new File(
this.getClass().getClassLoader().getResource("file/globalParam.json")
.getPath()));
file = new MockMultipartFile("file", "globalParam.json", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream);
paramMap = new LinkedMultiValueMap<>();
request = new EnvironmentImportRequest();
request.setCover(true);
paramMap.add("file", List.of(file));
paramMap.add("request", JSON.toJSONString(request));
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
request.setCover(false);
paramMap.clear();
paramMap.add("file", List.of(file));
paramMap.add("request", JSON.toJSONString(request));
requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID);
projectParametersMapper.deleteByExample(projectParametersExample);
inputStream = new FileInputStream(new File(
this.getClass().getClassLoader().getResource("file/txtFile.txt")
.getPath()));

View File

@ -107,9 +107,9 @@ public class EnvironmentGroupControllerTests extends BaseTest {
private List<HttpConfig> createHttpConfig() {
List<HttpConfig> httpConfigs = new ArrayList<>();
HttpConfig httpConfig = new HttpConfig();
List<KeyValue> headers = new ArrayList<>();
KeyValue keyValue = new KeyValue();
keyValue.setName("key");
List<KeyValueEnableParam> headers = new ArrayList<>();
KeyValueEnableParam keyValue = new KeyValueEnableParam();
keyValue.setKey("key");
keyValue.setValue("value");
headers.add(keyValue);
httpConfig.setHeaders(headers);
@ -314,6 +314,7 @@ public class EnvironmentGroupControllerTests extends BaseTest {
this.requestPostWithOkAndReturn(POS_URL, posRequest);
}
@Test
@Order(12)
public void testDeleteSuccess() throws Exception {

View File

@ -2,8 +2,9 @@ package io.metersphere.project.controller;
import io.metersphere.project.domain.Project;
import io.metersphere.project.dto.environment.GlobalParams;
import io.metersphere.project.dto.environment.GlobalParamsDTO;
import io.metersphere.project.dto.environment.GlobalParamsRequest;
import io.metersphere.project.dto.environment.KeyValue;
import io.metersphere.project.dto.environment.KeyValueEnableParam;
import io.metersphere.project.dto.environment.variables.CommonVariables;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.PermissionConstants;
@ -18,27 +19,41 @@ import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.invoker.ProjectServiceInvoker;
import io.metersphere.system.log.constants.OperationLogType;
import jakarta.annotation.Resource;
import org.apache.http.HttpHeaders;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class GlobalParamsControllerTests extends BaseTest {
@ -48,6 +63,8 @@ public class GlobalParamsControllerTests extends BaseTest {
private static final String add = prefix + "/add";
private static final String get = prefix + "/get/";
private static final String update = prefix + "/update";
private static final String export = prefix + "/export/%s";
private static final String importUrl = prefix + "/import";
private static final ResultMatcher BAD_REQUEST_MATCHER = status().isBadRequest();
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
@ -112,6 +129,7 @@ public class GlobalParamsControllerTests extends BaseTest {
envVariable.setName("name" + i);
envVariable.setValue("value" + i);
envVariable.setDescription("desc" + i);
envVariable.setTags(List.of("tag" + i));
envVariable.setType(VariableTypeConstants.CONSTANT.name());
commonVariables.add(envVariable);
}
@ -119,11 +137,11 @@ public class GlobalParamsControllerTests extends BaseTest {
}
//根据需要多长的list 生成不同的List<KeyValue> headers
private List<KeyValue> getHeaders(int length) {
List<KeyValue> headers = new ArrayList<>();
private List<KeyValueEnableParam> getHeaders(int length) {
List<KeyValueEnableParam> headers = new ArrayList<>();
for (int i = 0; i < length; i++) {
KeyValue header = new KeyValue();
header.setName("key" + i);
KeyValueEnableParam header = new KeyValueEnableParam();
header.setKey("key" + i);
header.setValue("value" + i);
headers.add(header);
}
@ -242,7 +260,7 @@ public class GlobalParamsControllerTests extends BaseTest {
globalParams.setCommonVariables(getEnvVariables(1));
request.setGlobalParams(globalParams);
MvcResult mvcResult = this.responsePost(add, request);
GlobalParamsRequest globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
ProjectParameters globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class);
Assertions.assertNotNull(globalParamsRequest);
ProjectParameters projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId());
Assertions.assertNotNull(projectParameters);
@ -258,7 +276,7 @@ public class GlobalParamsControllerTests extends BaseTest {
globalParams.setCommonVariables(new ArrayList<>());
request.setGlobalParams(globalParams);
mvcResult = this.responsePost(add, request);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class);
Assertions.assertNotNull(globalParamsRequest);
projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId());
Assertions.assertNotNull(projectParameters);
@ -274,7 +292,7 @@ public class GlobalParamsControllerTests extends BaseTest {
globalParams.setCommonVariables(getEnvVariables(1));
request.setGlobalParams(globalParams);
mvcResult = this.responsePost(add, request);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class);
Assertions.assertNotNull(globalParamsRequest);
projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId());
Assertions.assertNotNull(projectParameters);
@ -290,7 +308,7 @@ public class GlobalParamsControllerTests extends BaseTest {
globalParams.setCommonVariables(new ArrayList<>());
request.setGlobalParams(globalParams);
mvcResult = this.responsePost(add, request);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class);
Assertions.assertNotNull(globalParamsRequest);
projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId());
Assertions.assertNotNull(projectParameters);
@ -302,7 +320,7 @@ public class GlobalParamsControllerTests extends BaseTest {
request.setProjectId("projectId5");
request.setGlobalParams(new GlobalParams());
mvcResult = this.responsePost(add, request);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class);
Assertions.assertNotNull(globalParamsRequest);
//校验日志
checkLog(globalParamsRequest.getId(), OperationLogType.ADD);
@ -315,6 +333,10 @@ public class GlobalParamsControllerTests extends BaseTest {
//校验权限
request = new GlobalParamsRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
GlobalParams globalParams1 = new GlobalParams();
globalParams1.setHeaders(getHeaders(2));
globalParams1.setCommonVariables(getEnvVariables(2));
request.setGlobalParams(globalParams1);
//权限校验
requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD, add, request);
}
@ -352,7 +374,7 @@ public class GlobalParamsControllerTests extends BaseTest {
globalParams.setCommonVariables(getEnvVariables(2));
request.setGlobalParams(globalParams);
MvcResult mvcResult = this.responsePost(update, request);
GlobalParamsRequest globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
ProjectParameters globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class);
Assertions.assertNotNull(globalParamsRequest);
//校验日志
checkLog(globalParamsRequest.getId(), OperationLogType.UPDATE);
@ -365,10 +387,14 @@ public class GlobalParamsControllerTests extends BaseTest {
//校验权限
request = new GlobalParamsRequest();
example = new ProjectParametersExample();
example.createCriteria().andProjectIdEqualTo("100001100001");
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
projectParametersList = projectParametersMapper.selectByExample(example);
request.setProjectId("100001100001");
request.setProjectId(DEFAULT_PROJECT_ID);
request.setId(projectParametersList.get(0).getId());
GlobalParams globalParams1 = new GlobalParams();
globalParams1.setHeaders(getHeaders(3));
globalParams1.setCommonVariables(getEnvVariables(4));
request.setGlobalParams(globalParams1);
//权限校验
requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE, update, request);
@ -405,7 +431,7 @@ public class GlobalParamsControllerTests extends BaseTest {
public void testGetSuccess() throws Exception {
//获取全局参数
MvcResult mvcResult = this.responseGet(get + "projectId1");
GlobalParamsRequest globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
GlobalParamsDTO globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsDTO.class);
Assertions.assertNotNull(globalParamsRequest);
Assertions.assertEquals("projectId1", globalParamsRequest.getProjectId());
Assertions.assertEquals(2, globalParamsRequest.getGlobalParams().getHeaders().size());
@ -416,9 +442,161 @@ public class GlobalParamsControllerTests extends BaseTest {
//获取全局参数 全局参数不存在
mvcResult = this.responseGet(get + "projectId2");
globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class);
globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsDTO.class);
Assertions.assertNull(globalParamsRequest);
}
@Test
@Order(6)
public void testExportSuccess() throws Exception {
//导出全局参数
MvcResult mvcResult = this.requestGetDownloadFile(String.format(export, DEFAULT_PROJECT_ID), null);
byte[] fileBytes = mvcResult.getResponse().getContentAsByteArray();
Assertions.assertNotNull(fileBytes);
mockMvc.perform(getRequestBuilder(String.format(export, "321")))
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
.andExpect(status().is5xxServerError());
}
@Test
@Order(7)
public void testImportSuccess() throws Exception {
//导入全局参数
InputStream inputStream = new FileInputStream(new File(
this.getClass().getClassLoader().getResource("file/globalParams.json")
.getPath()));
MockMultipartFile file = new MockMultipartFile("file", "globalParams.json", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream);
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
paramMap.add("file", List.of(file));
requestMultipartWithOk(importUrl, paramMap);
paramMap.clear();
paramMap.add("file", List.of(new File(
this.getClass().getClassLoader().getResource("file/huanj.json")
.getPath())));
this.requestMultipart(importUrl, paramMap, status().is5xxServerError());
}
protected MvcResult requestMultipart(String url, MultiValueMap<String, Object> paramMap, ResultMatcher resultMatcher) throws Exception {
MockMultipartHttpServletRequestBuilder requestBuilder = getMultipartRequestBuilderWithParam(url, paramMap);
MockHttpServletRequestBuilder header = requestBuilder
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.header(org.springframework.http.HttpHeaders.ACCEPT_LANGUAGE, "zh-CN");
return mockMvc.perform(header)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(resultMatcher).andReturn();
}
private MockMultipartHttpServletRequestBuilder getMultipartRequestBuilderWithParam(String url, MultiValueMap<String, Object> paramMap) {
MockMultipartHttpServletRequestBuilder requestBuilder =
MockMvcRequestBuilders.multipart(getBasePath() + url);
paramMap.forEach((key, value) -> {
List list = value;
for (Object o : list) {
if (o instanceof List fileList) {
fileList.forEach(o1 -> {
if (o1 instanceof MockMultipartFile mockMultipartFile) {
try {
MockMultipartFile mockMultipartFile1 = null;
mockMultipartFile1 = new MockMultipartFile(key, mockMultipartFile.getOriginalFilename(),
MediaType.APPLICATION_OCTET_STREAM_VALUE, mockMultipartFile.getBytes());
requestBuilder.file(mockMultipartFile1);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
} else {
MockMultipartFile multipartFile = null;
multipartFile = new MockMultipartFile(key, null,
MediaType.APPLICATION_JSON_VALUE, o.toString().getBytes());
requestBuilder.file(multipartFile);
}
}
});
return requestBuilder;
}
protected ResultActions requestMultipartWithOk(String url, MultiValueMap<String, Object> paramMap, Object... uriVariables) throws Exception {
MockHttpServletRequestBuilder requestBuilder = getMultipartRequestBuilder(url, paramMap, uriVariables);
return mockMvc.perform(requestBuilder)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk());
}
private static MockMultipartFile getMockMultipartFile(String key, Object value) throws IOException {
MockMultipartFile multipartFile;
if (value instanceof File) {
File file = (File) value;
multipartFile = new MockMultipartFile(key, file.getName(),
MediaType.APPLICATION_OCTET_STREAM_VALUE, Files.readAllBytes(file.toPath()));
} else if (value instanceof MockMultipartFile) {
multipartFile = (MockMultipartFile) value;
// 有些地方的参数 name 写的是文件名这里统一处理成参数名 key
multipartFile = new MockMultipartFile(key, multipartFile.getOriginalFilename(),
MediaType.APPLICATION_OCTET_STREAM_VALUE, multipartFile.getBytes());
} else {
multipartFile = new MockMultipartFile(key, key,
MediaType.APPLICATION_JSON_VALUE, value.toString().getBytes());
}
return multipartFile;
}
private MockHttpServletRequestBuilder getMultipartRequestBuilder(String url,
MultiValueMap<String, Object> paramMap,
Object[] uriVariables) {
MockMultipartHttpServletRequestBuilder requestBuilder = getMultipartRequestBuilderWithParam(url, paramMap, uriVariables);
return requestBuilder
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.header(SessionConstants.CURRENT_PROJECT, DEFAULT_PROJECT_ID)
.header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN");
}
private MockMultipartHttpServletRequestBuilder getMultipartRequestBuilderWithParam(String url, MultiValueMap<String, Object> paramMap, Object[] uriVariables) {
MockMultipartHttpServletRequestBuilder requestBuilder =
MockMvcRequestBuilders.multipart(getBasePath() + url, uriVariables);
paramMap.forEach((key, value) -> {
List list = value;
for (Object o : list) {
try {
if (o == null) {
continue;
}
MockMultipartFile multipartFile;
if (o instanceof List) {
List listObject = ((List) o);
if (CollectionUtils.isEmpty(listObject)) {
continue;
}
if (listObject.get(0) instanceof File || listObject.get(0) instanceof MockMultipartFile) {
// 参数是多个文件时,设置多个文件
for (Object subObject : ((List) o)) {
multipartFile = getMockMultipartFile(key, subObject);
requestBuilder.file(multipartFile);
}
} else {
multipartFile = getMockMultipartFile(key, o);
requestBuilder.file(multipartFile);
}
} else {
multipartFile = getMockMultipartFile(key, o);
requestBuilder.file(multipartFile);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
return requestBuilder;
}
}

View File

@ -1 +0,0 @@
{"globalParam":true,"environment":false,"data":"{\"headers\":[{\"name\":\"key0\",\"value\":\"value0\",\"enable\":true}],\"commonVariables\":[{\"id\":null,\"name\":\"name0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"desc0\"}]}"}

View File

@ -0,0 +1,69 @@
{
"id":"1204738326536684",
"projectId":"100001100001",
"globalParams":{
"headers":[
{
"name":"key0",
"value":"value0",
"enable":true
},
{
"name":"key1",
"value":"value1",
"enable":true
},
{
"name":"key2",
"value":"value2",
"enable":true
}
],
"commonVariables":[
{
"id":null,
"name":"name0",
"type":"CONSTANT",
"value":"value0",
"enable":true,
"description":"desc0",
"tags":[
"tag0"
]
},
{
"id":null,
"name":"name1",
"type":"CONSTANT",
"value":"value1",
"enable":true,
"description":"desc1",
"tags":[
"tag1"
]
},
{
"id":null,
"name":"name2",
"type":"CONSTANT",
"value":"value2",
"enable":true,
"description":"desc2",
"tags":[
"tag2"
]
},
{
"id":null,
"name":"name4",
"type":"CONSTANT",
"value":"value4",
"enable":true,
"description":"desc4",
"tags":[
"tag4"
]
}
]
}
}

File diff suppressed because one or more lines are too long