场景支持导入postman

This commit is contained in:
chenjianxing 2021-02-19 11:30:08 +08:00
parent c7046993e5
commit c24ca8e562
18 changed files with 272 additions and 73 deletions

View File

@ -2,9 +2,11 @@ package io.metersphere.api.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.JmxInfoDTO;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.base.domain.ApiScenario;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
@ -146,5 +148,11 @@ public class ApiAutomationController {
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileOperationRequest.getName() + "\"")
.body(bytes);
}
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public ApiDefinitionImport testCaseImport(@RequestPart(value = "file", required = false) MultipartFile file, @RequestPart("request") ApiTestImportRequest request) {
return apiAutomationService.scenarioImport(file, request);
}
}

View File

@ -13,8 +13,6 @@ public class ApiTestImportRequest {
private String projectId;
private String platform;
private Boolean useEnvironment;
// 来自场景的导入不需要存储
private boolean saved = true;
private String swaggerUrl;
//导入策略
private String modeId;

View File

@ -1,5 +1,6 @@
package io.metersphere.api.dto.definition.parse;
import io.metersphere.api.dto.definition.request.MsScenario;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import lombok.Data;
@ -12,6 +13,9 @@ public class ApiDefinitionImport {
private String protocol;
private List<ApiDefinitionWithBLOBs> data;
//导入场景
private MsScenario scenarioDefinition;
// 新版本带用例导出
private List<ApiTestCaseWithBLOBs> cases;
}

View File

@ -75,7 +75,7 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
return null;
}
protected ApiModule buildModule(ApiModule parentModule, String name, boolean isSaved) {
protected ApiModule buildModule(ApiModule parentModule, String name) {
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
ApiModule module;
if (parentModule != null) {
@ -84,9 +84,7 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
} else {
module = apiModuleService.getNewModule(name, this.projectId, 1);
}
if (isSaved) {
createModule(module);
}
createModule(module);
return module;
}

View File

@ -0,0 +1,15 @@
package io.metersphere.api.parse;
import io.metersphere.commons.constants.ApiImportPlatform;
import org.apache.commons.lang3.StringUtils;
public class ApiScenarioImportParserFactory {
public static ApiImportParser getApiImportParser(String platform) {
if (StringUtils.equals(ApiImportPlatform.Metersphere.name(), platform)) {
return new MsParser();
} else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) {
return new ScenarioPostmanParser();
}
return null;
}
}

View File

@ -73,7 +73,7 @@ public class MsParser extends ApiImportAbstractParser {
testObject.keySet().forEach(tag -> {
ApiModule parentModule = getSelectModule(importRequest.getModuleId());
ApiModule module = buildModule(parentModule, tag, importRequest.isSaved());
ApiModule module = buildModule(parentModule, tag);
JSONObject requests = testObject.getJSONObject(tag);
requests.keySet().forEach(requestName -> {
@ -181,7 +181,7 @@ public class MsParser extends ApiImportAbstractParser {
Iterator<String> iterator = modules.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
parent = buildModule(parent, item, importRequest.isSaved());
parent = buildModule(parent, item);
if (!iterator.hasNext()) {
apiDefinition.setModuleId(parent.getId());
}

View File

@ -33,17 +33,20 @@ public class PostmanParser extends ApiImportAbstractParser {
List<PostmanKeyValue> variables = postmanCollection.getVariable();
ApiDefinitionImport apiImport = new ApiDefinitionImport();
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
parseItem(postmanCollection.getItem(), variables, results, buildModule(getSelectModule(request.getModuleId()), postmanCollection.getInfo().getName(), request.isSaved()), request.isSaved());
parseItem(postmanCollection.getItem(), variables, results, buildModule(getSelectModule(request.getModuleId()), postmanCollection.getInfo().getName()), true);
apiImport.setData(results);
return apiImport;
}
private void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, List<ApiDefinitionWithBLOBs> results, ApiModule parentModule, boolean isSaved) {
protected void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, List<ApiDefinitionWithBLOBs> results, ApiModule parentModule, Boolean isCreateModule) {
for (PostmanItem item : items) {
List<PostmanItem> childItems = item.getItem();
if (childItems != null) {
ApiModule module = buildModule(parentModule, item.getName() , isSaved);
parseItem(childItems, variables, results, module, isSaved);
ApiModule module = null;
if (isCreateModule) {
module = buildModule(parentModule, item.getName());
}
parseItem(childItems, variables, results, module, isCreateModule);
} else {
ApiDefinitionWithBLOBs request = parsePostman(item);
if (request != null) {

View File

@ -0,0 +1,40 @@
package io.metersphere.api.parse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.definition.request.MsScenario;
import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.parse.postman.PostmanCollection;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import io.metersphere.base.domain.ApiModule;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ScenarioPostmanParser extends PostmanParser {
@Override
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
this.projectId = request.getProjectId();
ApiDefinitionImport apiImport = new ApiDefinitionImport();
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
PostmanCollection postmanCollection = JSON.parseObject(getApiTestStr(source), PostmanCollection.class);
parseItem(postmanCollection.getItem(), postmanCollection.getVariable(), results, null, false);
MsScenario msScenario = new MsScenario();
LinkedList<MsTestElement> msHTTPSamplerProxies = new LinkedList<>();
results.forEach(res -> {
msHTTPSamplerProxies.add(JSONObject.parseObject(res.getRequest(), MsHTTPSamplerProxy.class));
});
msScenario.setHashTree(msHTTPSamplerProxies);
msScenario.setType("scenario");
msScenario.setName(postmanCollection.getInfo().getName());
apiImport.setScenarioDefinition(msScenario);
return apiImport;
}
}

View File

@ -71,7 +71,7 @@ public class Swagger2Parser extends SwaggerAbstractParser {
addBodyHeader(request);
apiDefinition.setRequest(JSON.toJSONString(request));
apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation, operation.getResponses())));
buildModule(parentNode, apiDefinition, operation.getTags(), importRequest.isSaved());
buildModule(parentNode, apiDefinition, operation.getTags());
results.add(apiDefinition);
}
}

View File

@ -103,7 +103,7 @@ public class Swagger3Parser extends SwaggerAbstractParser {
addBodyHeader(request);
apiDefinition.setRequest(JSON.toJSONString(request));
apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation.getResponses())));
buildModule(parentNode, apiDefinition, operation.getTags(), importRequest.isSaved());
buildModule(parentNode, apiDefinition, operation.getTags());
results.add(apiDefinition);
}
}

View File

@ -7,10 +7,10 @@ import java.util.List;
public abstract class SwaggerAbstractParser extends ApiImportAbstractParser {
protected void buildModule(ApiModule parentModule, ApiDefinitionWithBLOBs apiDefinition, List<String> tags, boolean isSaved) {
protected void buildModule(ApiModule parentModule, ApiDefinitionWithBLOBs apiDefinition, List<String> tags) {
if (tags != null) {
tags.forEach(tag -> {
ApiModule module = buildModule(parentModule, tag, isSaved);
ApiModule module = buildModule(parentModule, tag);
apiDefinition.setModuleId(module.getId());
});
}

View File

@ -5,15 +5,19 @@ import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.DeleteAPIReportRequest;
import io.metersphere.api.dto.JmxInfoDTO;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.definition.request.*;
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.parse.ApiImportParser;
import io.metersphere.api.parse.ApiScenarioImportParserFactory;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
@ -143,32 +147,11 @@ public class ApiAutomationService {
request.setId(UUID.randomUUID().toString());
checkNameExist(request);
final ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs();
scenario.setId(request.getId());
scenario.setName(request.getName());
scenario.setProjectId(request.getProjectId());
scenario.setTags(request.getTags());
scenario.setApiScenarioModuleId(request.getApiScenarioModuleId());
scenario.setModulePath(request.getModulePath());
scenario.setLevel(request.getLevel());
scenario.setFollowPeople(request.getFollowPeople());
scenario.setPrincipal(request.getPrincipal());
scenario.setStepTotal(request.getStepTotal());
scenario.setScenarioDefinition(JSON.toJSONString(request.getScenarioDefinition()));
final ApiScenarioWithBLOBs scenario = buildSaveScenario(request);
scenario.setCreateTime(System.currentTimeMillis());
scenario.setUpdateTime(System.currentTimeMillis());
scenario.setNum(getNextNum(request.getProjectId()));
if (StringUtils.isNotEmpty(request.getStatus())) {
scenario.setStatus(request.getStatus());
} else {
scenario.setStatus(ScenarioStatus.Underway.name());
}
if (request.getUserId() == null) {
scenario.setUserId(SessionUtils.getUserId());
} else {
scenario.setUserId(request.getUserId());
}
scenario.setDescription(request.getDescription());
apiScenarioMapper.insert(scenario);
List<String> bodyUploadIds = request.getBodyUploadIds();
@ -190,7 +173,12 @@ public class ApiAutomationService {
List<String> bodyUploadIds = request.getBodyUploadIds();
FileUtils.createBodyFiles(bodyUploadIds, bodyFiles);
final ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs();
final ApiScenarioWithBLOBs scenario = buildSaveScenario(request);
apiScenarioMapper.updateByPrimaryKeySelective(scenario);
}
public ApiScenarioWithBLOBs buildSaveScenario(SaveApiScenarioRequest request) {
ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs();
scenario.setId(request.getId());
scenario.setName(request.getName());
scenario.setProjectId(request.getProjectId());
@ -201,16 +189,19 @@ public class ApiAutomationService {
scenario.setFollowPeople(request.getFollowPeople());
scenario.setPrincipal(request.getPrincipal());
scenario.setStepTotal(request.getStepTotal());
scenario.setScenarioDefinition(JSON.toJSONString(request.getScenarioDefinition()));
scenario.setUpdateTime(System.currentTimeMillis());
scenario.setScenarioDefinition(JSON.toJSONString(request.getScenarioDefinition()));
if (StringUtils.isNotEmpty(request.getStatus())) {
scenario.setStatus(request.getStatus());
} else {
scenario.setStatus(ScenarioStatus.Underway.name());
}
scenario.setUserId(request.getUserId());
scenario.setDescription(request.getDescription());
apiScenarioMapper.updateByPrimaryKeySelective(scenario);
if (request.getUserId() == null) {
scenario.setUserId(SessionUtils.getUserId());
} else {
scenario.setUserId(request.getUserId());
}
return scenario;
}
public void delete(String id) {
@ -732,4 +723,27 @@ public class ApiAutomationService {
});
}
}
public ApiDefinitionImport scenarioImport(MultipartFile file, ApiTestImportRequest request) {
ApiImportParser apiImportParser = ApiScenarioImportParserFactory.getApiImportParser(request.getPlatform());
ApiDefinitionImport apiImport = null;
try {
apiImport = apiImportParser.parse(file == null ? null : file.getInputStream(), request);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
MSException.throwException(Translator.get("parse_data_error"));
}
SaveApiScenarioRequest saveReq = new SaveApiScenarioRequest();
saveReq.setScenarioDefinition(apiImport.getScenarioDefinition());
saveReq.setName(saveReq.getScenarioDefinition().getName());
saveReq.setProjectId(request.getProjectId());
saveReq.setApiScenarioModuleId(request.getModuleId());
if (StringUtils.isNotBlank(request.getUserId())) {
saveReq.setPrincipal(request.getUserId());
} else {
saveReq.setPrincipal(SessionUtils.getUserId());
}
create(saveReq, new ArrayList<>());
return apiImport;
}
}

View File

@ -498,9 +498,7 @@ public class ApiDefinitionService {
LogUtil.error(e.getMessage(), e);
MSException.throwException(Translator.get("parse_data_error"));
}
if (request.isSaved()) {
importApi(request, apiImport);
}
importApi(request, apiImport);
return apiImport;
}

View File

@ -46,10 +46,6 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
@Resource
TestPlanProjectService testPlanProjectService;
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private ApiDefinitionService apiDefinitionService;
@Resource
private ProjectService projectService;
public ApiScenarioModuleService() {

View File

@ -29,7 +29,6 @@ public class SwaggerUrlImportJob extends MsScheduleJob {
request.setSwaggerUrl(swaggerUrlProject.getSwaggerUrl());
request.setModuleId(swaggerUrlProject.getModuleId());
request.setPlatform("Swagger2");
request.setSaved(true);
request.setUserId(jobDataMap.getString("userId"));
request.setType("schedule");
apiDefinitionService.apiTestImport(null, request);

View File

@ -16,12 +16,14 @@
ref="nodeTree">
<template v-slot:header>
<el-input :placeholder="$t('test_track.module.search')" v-model="condition.filterText" size="small">
<template v-slot:append>
<el-button v-if="!isReadOnly" icon="el-icon-folder-add" @click="addScenario" v-tester/>
</template>
</el-input>
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/>
<api-scenario-module-header
:condition="condition"
:current-module="currentModule"
:is-read-only="isReadOnly"
@exportAPI="exportAPI"
@addScenario="addScenario"
@refreshTable="$emit('refreshTable')"
@refresh="refresh"/>
</template>
</ms-node-tree>
@ -41,10 +43,12 @@ import {getCurrentProjectID} from "@/common/js/utils";
import MsNodeTree from "../../../track/common/NodeTree";
import {buildNodePath} from "../../definition/model/NodeTree";
import ModuleTrashButton from "../../definition/components/module/ModuleTrashButton";
import ApiScenarioModuleHeader from "@/business/components/api/automation/scenario/module/ApiScenarioModuleHeader";
export default {
name: 'MsApiScenarioModule',
components: {
ApiScenarioModuleHeader,
ModuleTrashButton,
MsNodeTree,
MsAddBasisScenario,
@ -175,9 +179,9 @@ export default {
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
}
},
// exportAPI() {
// this.$emit('exportAPI');
// },
exportAPI() {
this.$emit('exportAPI');
},
// debug() {
// this.$emit('debug');
// },

View File

@ -0,0 +1,111 @@
<template>
<div>
<el-input :placeholder="$t('test_track.module.search')" v-model="condition.filterText" size="small">
<template v-slot:append>
<el-dropdown v-if="!isReadOnly" size="small" split-button type="primary" class="ms-api-button" @click="handleCommand('add-api')"
v-tester
@command="handleCommand">
<el-button icon="el-icon-folder-add" @click="addScenario"></el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item>
<el-dropdown-item command="export">{{ $t('report.export') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-input>
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/>
<api-import :model="'scenario'" ref="apiImport" :moduleOptions="moduleOptions" @refresh="$emit('refresh')"/>
</div>
</template>
<script>
import {getCurrentProjectID} from "../../../../../../common/js/utils";
import {buildNodePath} from "@/business/components/api/definition/model/NodeTree";
import ModuleTrashButton from "@/business/components/api/definition/components/module/ModuleTrashButton";
import ApiImport from "@/business/components/api/definition/components/import/ApiImport";
export default {
name: "ApiScenarioModuleHeader",
components: {ApiImport, ModuleTrashButton},
data() {
return {
// options: OPTIONS,
moduleOptions: {}
}
},
props: {
condition: {
type: Object,
default() {
return {}
}
},
currentModule: {
type: Object,
default() {
return {}
}
},
isReadOnly: {
type: Boolean,
default() {
return false
}
},
},
methods: {
handleCommand(e) {
switch (e) {
case "import":
if (!getCurrentProjectID()) {
this.$warning(this.$t('commons.check_project_tip'));
return;
}
this.result = this.$get("/api/automation/module/list/" + getCurrentProjectID() + "/", response => {
if (response.data != undefined && response.data != null) {
this.data = response.data;
let moduleOptions = [];
this.data.forEach(node => {
buildNodePath(node, {path: ''}, moduleOptions);
});
this.moduleOptions = moduleOptions
}
});
this.$refs.apiImport.open(this.currentModule);
break;
default:
if (!getCurrentProjectID()) {
this.$warning(this.$t('commons.check_project_tip'));
return;
}
this.$emit('exportAPI');
break;
}
},
addScenario() {
this.$emit('addScenario');
},
refresh() {
this.$emit('refresh');
},
enableTrash() {
this.condition.trashEnable = true;
}
}
}
</script>
<style scoped>
.read-only {
width: 150px !important;
}
.filter-input {
width: 174px;
padding-left: 3px;
}
</style>

View File

@ -5,7 +5,7 @@
<div class="header-bar">
<div>{{ $t('api_test.api_import.data_format') }}</div>
<el-radio-group v-model="selectedPlatformValue">
<el-radio v-for="(item, index) in platforms" :key="index" :label="item.value">{{ item.name }}</el-radio>
<el-radio v-for="(item, index) in platforms" v-if="!isScenarioModel || item.name != 'Swagger'" :key="index" :label="item.value">{{ item.name }}</el-radio>
</el-radio-group>
<div class="operate-button">
@ -26,14 +26,14 @@
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item :label="$t('commons.import_mode')">
<el-form-item v-if="!isScenarioModel" :label="$t('commons.import_mode')">
<el-select size="small" v-model="formData.modeId" class="project-select" clearable>
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item v-if="isSwagger2">
<el-switch
v-model="swaggerUrlEable"
v-model="swaggerUrlEnable"
:active-text="$t('api_test.api_import.swagger_url_import')">
</el-switch>
</el-form-item>
@ -42,7 +42,7 @@
<el-col :span="1">
<el-divider direction="vertical"/>
</el-col>
<el-col :span="12" v-show="isSwagger2 && swaggerUrlEable" style="margin-top: 40px">
<el-col :span="12" v-show="isSwagger2 && swaggerUrlEnable" style="margin-top: 40px">
<el-form-item :label="'Swagger URL'" prop="swaggerUrl" class="swagger-url">
<el-input size="small" v-model="formData.swaggerUrl" clearable show-word-limit/>
</el-form-item>
@ -56,7 +56,7 @@
</el-form-item>
</el-col>
<el-col :span="12"
v-if="selectedPlatformValue != 'Swagger2' || (selectedPlatformValue == 'Swagger2' && !swaggerUrlEable)">
v-if="selectedPlatformValue != 'Swagger2' || (selectedPlatformValue == 'Swagger2' && !swaggerUrlEnable)">
<el-upload
class="api-upload"
drag
@ -93,7 +93,6 @@ import MsDialogFooter from "../../../../common/components/MsDialogFooter";
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
import {getCurrentProjectID} from "../../../../../../common/js/utils";
import ScheduleImport from "@/business/components/api/definition/components/import/ImportScheduleEdit";
import {buildNodePath} from "@/business/components/api/definition/model/NodeTree";
export default {
name: "ApiImport",
@ -103,12 +102,16 @@ export default {
type: Boolean,
default: true,
},
moduleOptions: {}
moduleOptions: {},
model: {
type: String,
default: 'definition'
}
},
data() {
return {
visible: false,
swaggerUrlEable: false,
swaggerUrlEnable: false,
swaggerSynchronization: false,
showEnvironmentSelect: true,
modeOptions: [{
@ -176,6 +179,9 @@ export default {
computed: {
isSwagger2() {
return this.selectedPlatformValue === 'Swagger2';
},
isScenarioModel() {
return this.model === 'scenario';
}
},
methods: {
@ -222,12 +228,16 @@ export default {
save() {
this.$refs.form.validate(valid => {
if (valid) {
if ((this.selectedPlatformValue != 'Swagger2' || (this.selectedPlatformValue == 'Swagger2' && !this.swaggerUrlEable)) && !this.formData.file) {
if ((this.selectedPlatformValue != 'Swagger2' || (this.selectedPlatformValue == 'Swagger2' && !this.swaggerUrlEnable)) && !this.formData.file) {
this.$warning(this.$t('commons.please_upload'));
return;
}
let url = '/api/definition/import';
if (this.isScenarioModel) {
url = '/api/automation/import';
}
let param = this.buildParam();
this.result = this.$fileUpload('/api/definition/import', param.file, null, this.buildParam(), response => {
this.result = this.$fileUpload(url, param.file, null, this.buildParam(), response => {
let res = response.data;
this.$success(this.$t('test_track.case.import.success'));
this.visible = false;
@ -243,6 +253,7 @@ export default {
Object.assign(param, this.formData);
param.platform = this.selectedPlatformValue;
param.saved = this.saved;
param.model = this.model;
if (this.currentModule) {
param.moduleId = this.formData.moduleId
this.moduleOptions.filter(item => {
@ -253,7 +264,7 @@ export default {
param.modeId = this.formData.modeId
}
param.projectId = getCurrentProjectID();
if (!this.swaggerUrlEable) {
if (!this.swaggerUrlEnable) {
param.swaggerUrl = undefined;
}
return param;