diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java index 54ec106dbc..31fed91906 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java @@ -13,6 +13,7 @@ import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult; import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest; import io.metersphere.api.service.ApiDefinitionService; import io.metersphere.api.service.EsbApiParamService; +import io.metersphere.api.service.EsbImportService; import io.metersphere.base.domain.ApiDefinition; import io.metersphere.base.domain.Schedule; import io.metersphere.commons.constants.RoleConstants; @@ -32,6 +33,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import java.net.MalformedURLException; import java.util.Date; import java.util.List; @@ -49,6 +51,8 @@ public class ApiDefinitionController { private CheckPermissionService checkPermissionService; @Resource private EsbApiParamService esbApiParamService; + @Resource + private EsbImportService esbImportService; @PostMapping("/list/{goPage}/{pageSize}") public Pager> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody ApiDefinitionRequest request) { @@ -254,4 +258,10 @@ public class ApiDefinitionController { public String preview(@RequestBody String jsonSchema) { return JSONSchemaGenerator.getJson(jsonSchema); } + + @GetMapping("/export/esbExcelTemplate") + @RequiresRoles(value = {RoleConstants.ADMIN, RoleConstants.ORG_ADMIN, RoleConstants.TEST_MANAGER}, logical = Logical.OR) + public void testCaseTemplateExport(HttpServletResponse response) { + esbImportService.templateExport(response); + } } diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/EsbDataStruct.java b/backend/src/main/java/io/metersphere/api/dto/automation/EsbDataStruct.java index 0fa226b32f..49f30fdfcd 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/EsbDataStruct.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/EsbDataStruct.java @@ -8,6 +8,7 @@ import org.dom4j.Element; import java.util.ArrayList; import java.util.List; +import java.util.UUID; /** * //ESB数据格式 @@ -19,15 +20,69 @@ import java.util.List; @Getter @Setter public class EsbDataStruct { + private String uuid; private String name; private String value; private String type; private String systemName; private String contentType; - private String required; + private boolean required; private String description; private List children; + public void init(){ + this.uuid = UUID.randomUUID().toString(); + this.systemName = ""; + this.description = ""; + this.value=""; + this.required = true; + this.contentType = ""; + this.type = ""; + this.children = new ArrayList<>(); + } + + public boolean initDefaultData(String name, String typeLength,String chineseName,String desc){ + this.init(); + if(StringUtils.isEmpty(name)){return false; } + if(typeLength == null){ + typeLength = ""; + }else{ + typeLength = typeLength.trim(); + typeLength = typeLength.toLowerCase(); + } + + this.name = name; + + if(typeLength.startsWith("string")){ + this.type = "string"; + String lengthStr = typeLength.substring(6); + if(lengthStr.startsWith("(") && lengthStr.endsWith(")")){ + try { + int length = Integer.parseInt(lengthStr.substring(1,lengthStr.length()-1)); + this.contentType = String.valueOf(length); + }catch (Exception e){ } + + } + }else if(typeLength.startsWith("array")){ + this.type = "array"; + }else{ + this.type = "object"; + } + + if(StringUtils.isEmpty(desc)){desc = "";} + if(StringUtils.isNotEmpty(chineseName)){ + this.description = chineseName+":"+desc; + }else{ + this.description =desc; + } + + if(this.description.endsWith(":")){ + this.description = this.description.substring(0,this.description.length()-1); + } + + return true; + } + public EsbDataStruct copy(boolean copyChildren) { EsbDataStruct returnObj = new EsbDataStruct(); returnObj.name = this.name; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java index c58d775624..cc1c6626d7 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java @@ -1,12 +1,12 @@ 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.ApiScenarioWithBLOBs; import io.metersphere.base.domain.ApiTestCaseWithBLOBs; +import io.metersphere.base.domain.EsbApiParamsWithBLOBs; import lombok.Data; import java.util.List; +import java.util.Map; @Data public class ApiDefinitionImport { @@ -16,4 +16,7 @@ public class ApiDefinitionImport { // 新版本带用例导出 private List cases; + + //ESB文件导入的附属数据类 + private Map esbApiParamsMap; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java index f7db9334b0..3fb2000af7 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java @@ -14,6 +14,8 @@ public class ApiDefinitionImportParserFactory { return new Swagger2Parser(); }else if (StringUtils.equals(ApiImportPlatform.Har.name(), platform)) { return new HarParser(); + }else if (StringUtils.equals(ApiImportPlatform.ESB.name(), platform)) { + return new ESBParser(); } return null; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ESBParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ESBParser.java new file mode 100644 index 0000000000..0c6c51fdd0 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ESBParser.java @@ -0,0 +1,769 @@ +package io.metersphere.api.dto.definition.parse; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import io.metersphere.api.dto.ApiTestImportRequest; +import io.metersphere.api.dto.automation.EsbDataStruct; +import io.metersphere.api.dto.definition.parse.esb.EsbExcelDataStruct; +import io.metersphere.api.dto.definition.parse.esb.EsbSheetDataStruct; +import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; +import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; +import io.metersphere.api.dto.scenario.request.RequestType; +import io.metersphere.base.domain.ApiDefinitionWithBLOBs; +import io.metersphere.base.domain.ApiModule; +import io.metersphere.base.domain.EsbApiParamsWithBLOBs; +import io.metersphere.commons.utils.SessionUtils; +import io.swagger.models.Model; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.*; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.net.URLEncoder; +import java.text.DateFormat; +import java.util.*; +import java.util.regex.Pattern; + +/** + * @author song.tianyang + * @Date 2021/3/10 11:14 上午 + * @Description + */ +public class ESBParser extends EsbAbstractParser { + + private final int REQUEST_MESSAGE_ROW = 5; + + private Map definitions = null; + + public static void export(HttpServletResponse response, String fileName) { + + XSSFWorkbook wb = null; + ServletOutputStream out = null; + try { + wb = getTemplate(); + out = response.getOutputStream(); + response.reset(); + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx"); + wb.write(out); + wb.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (out != null) { + try { + out.close(); + } catch (Exception e) { + + } + } + if (wb != null) { + try { + wb.close(); + } catch (Exception e) { + + } + } + } + } + + private static XSSFWorkbook getTemplate() { + XSSFWorkbook workbook = new XSSFWorkbook(); + XSSFFont font = workbook.createFont(); + font.setFontHeightInPoints((short) 9); + Map cellStyleMap = createCellStle(workbook); + XSSFSheet headSheet = workbook.createSheet("公共报文头"); + generateSheet(headSheet,true, font,cellStyleMap); + XSSFSheet bodySheet = workbook.createSheet("接口报文信息"); + generateSheet(bodySheet, false,font,cellStyleMap); + return workbook; + } + + private static Map createCellStle(XSSFWorkbook workbook) { + Map cellStype = new HashMap<>(); + short[] colorIndexArr = {IndexedColors.LIGHT_GREEN.getIndex(), IndexedColors.ORCHID.getIndex(), IndexedColors.YELLOW.getIndex()}; + for (short colorIndex : colorIndexArr) { + XSSFCellStyle style = workbook.createCellStyle(); +// style.setFillForegroundColor(IndexedColors.VIOLET.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setBorderBottom(BorderStyle.THIN); + style.setBorderLeft(BorderStyle.THIN); + style.setBorderRight(BorderStyle.THIN); + style.setBorderTop(BorderStyle.THIN); + + String name = ""; + if(colorIndex == IndexedColors.LIGHT_GREEN.getIndex()){ + style.setFillForegroundColor(new XSSFColor(new java.awt.Color(204, 255, 204))); + name = "green"; + }else if(colorIndex == IndexedColors.ORCHID.getIndex()){ + style.setFillForegroundColor(new XSSFColor(new java.awt.Color(151, 50, 101))); + name = "pop"; + }else if(colorIndex == IndexedColors.YELLOW.getIndex()){ + style.setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 255, 153))); + name = "yellow"; + }else{ + name = "default"; + } + cellStype.put(name,style); + } + return cellStype; + } + + private static void generateSheet(XSSFSheet sheet,boolean isHead, XSSFFont font,Map cellStyleMap) { + if (sheet == null) { + return; + } + + sheet.setColumnWidth(0, 4000); + sheet.setColumnWidth(1, 4000); + sheet.setColumnWidth(2, 4000); + sheet.setColumnWidth(3, 4000); + if(isHead){ + sheet.setColumnWidth(4, 880); + sheet.setColumnWidth(5, 4000); + sheet.setColumnWidth(6, 4000); + sheet.setColumnWidth(7, 4000); + sheet.setColumnWidth(8, 4000); + sheet.setColumnWidth(9, 4000); + }else { + sheet.setColumnWidth(4, 4000); + sheet.setColumnWidth(5, 880); + sheet.setColumnWidth(6, 4000); + sheet.setColumnWidth(7, 4000); + sheet.setColumnWidth(8, 4000); + sheet.setColumnWidth(9, 4000); + sheet.setColumnWidth(10, 4000); + } + + /** + * 模版生成: + * 字体大小:9 + * row1: 1交易码 2交易名称 (head的话是5)6(紫色[pop]背景空白单元格,下同) 7服务名称 8服务场景 + * row2: 1.请输入交易码(必填) 2请输入交易名称(必填) 7请输入服务名称(如果不填,则以交易名称为主) 8请输入服务场景(选填) + * row3: 合并7-10单元格,输入:请输入系统名称 背景色:黄色[yellow] + * row4: 1.英文名称2.中文名称3.数据类型/长度4.是否必输5.备注 7.英文名称8.数据类型/长度9.中文名称 10备注 背景色:黄色 + * row5: 整行都是青色【green】,1:输入 + * row6: 3:请输入STRING(具体长度) 或 ARRAY; 8:同3 + * row7:无 + * row8: 整行都是青色,1:输出 + * row9: 3:请输入STRING(具体长度) 或 ARRAY; 8:同3 + */ + XSSFRow row1 = sheet.createRow(0); + setCellValue("交易码", row1.createCell(0), font,cellStyleMap.get("default")); + setCellValue("交易名称", row1.createCell(1), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(2), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(3), font,cellStyleMap.get("default")); + if(isHead){ + setCellValue("", row1.createCell(4), font,cellStyleMap.get("default")); + setCellValue("服务名称", row1.createCell(5), font,cellStyleMap.get("default")); + setCellValue("服务场景", row1.createCell(6), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(9), font,cellStyleMap.get("default")); + + }else{ + setCellValue("", row1.createCell(4), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(5), font,cellStyleMap.get("pop")); + setCellValue("服务名称", row1.createCell(6), font,cellStyleMap.get("default")); + setCellValue("服务场景", row1.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(9), font,cellStyleMap.get("default")); + setCellValue("", row1.createCell(10), font,cellStyleMap.get("default")); + } + + + XSSFRow row2 = sheet.createRow(1); + setCellValue("请输入交易码(必填)", row2.createCell(0), font,cellStyleMap.get("default")); + setCellValue("请输入交易名称(必填)", row2.createCell(1), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(2), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(3), font,cellStyleMap.get("default")); + if(isHead){ + setCellValue("", row2.createCell(4), font,cellStyleMap.get("pop")); + setCellValue("请输入服务名称(如果不填,则以交易名称为主)", row2.createCell(5), font,null); + setCellValue("请输入服务场景(选填)", row2.createCell(6), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(9), font,cellStyleMap.get("default")); + }else{ + setCellValue("", row2.createCell(4), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(5), font,cellStyleMap.get("pop")); + setCellValue("请输入服务名称(如果不填,则以交易名称为主)", row2.createCell(6), font,null); + setCellValue("请输入服务场景(选填)", row2.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(9), font,cellStyleMap.get("default")); + setCellValue("", row2.createCell(10), font,cellStyleMap.get("default")); + } + + XSSFRow row3 = sheet.createRow(2); + setCellValue("", row3.createCell(0), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(1), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(2), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(3), font,cellStyleMap.get("yellow")); + if(isHead){ + setCellValue("", row3.createCell(4), font,cellStyleMap.get("yellow")); + setCellValue("请输入系统名称", row3.createCell(5), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(6), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(7), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(8), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(9), font,cellStyleMap.get("yellow")); + CellRangeAddress region1 = new CellRangeAddress(2, 2, 0, 3); + sheet.addMergedRegion(region1); + CellRangeAddress region2 = new CellRangeAddress(2, 2, 5, 9); + sheet.addMergedRegion(region2); + }else{ + setCellValue("", row3.createCell(4), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(5), font,cellStyleMap.get("yellow")); + setCellValue("请输入系统名称", row3.createCell(6), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(7), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(8), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(9), font,cellStyleMap.get("yellow")); + setCellValue("", row3.createCell(10), font,cellStyleMap.get("yellow")); + CellRangeAddress region1 = new CellRangeAddress(2, 2, 0, 4); + sheet.addMergedRegion(region1); + CellRangeAddress region2 = new CellRangeAddress(2, 2, 6, 10); + sheet.addMergedRegion(region2); + } + + XSSFRow row4 = sheet.createRow(3); + setCellValue("英文名称", row4.createCell(0), font,cellStyleMap.get("yellow")); + setCellValue("中文名称", row4.createCell(1), font,cellStyleMap.get("yellow")); + setCellValue("数据类型/长度", row4.createCell(2), font,cellStyleMap.get("yellow")); + if(isHead){ + setCellValue("备注", row4.createCell(3), font,cellStyleMap.get("yellow")); + setCellValue("", row4.createCell(4), font,cellStyleMap.get("pop")); + setCellValue("英文名称", row4.createCell(5), font,cellStyleMap.get("yellow")); + setCellValue("数据类型/长度", row4.createCell(6), font,cellStyleMap.get("yellow")); + setCellValue("中文名称", row4.createCell(7), font,cellStyleMap.get("yellow")); + setCellValue("备注", row4.createCell(8), font,cellStyleMap.get("yellow")); + setCellValue("所在报文位置", row4.createCell(9), font,cellStyleMap.get("yellow")); + }else { + setCellValue("是否必输", row4.createCell(3), font,cellStyleMap.get("yellow")); + setCellValue("备注", row4.createCell(4), font,cellStyleMap.get("yellow")); + setCellValue("", row4.createCell(5), font,cellStyleMap.get("pop")); + setCellValue("英文名称", row4.createCell(6), font,cellStyleMap.get("yellow")); + setCellValue("数据类型/长度", row4.createCell(7), font,cellStyleMap.get("yellow")); + setCellValue("中文名称", row4.createCell(8), font,cellStyleMap.get("yellow")); + setCellValue("备注", row4.createCell(9), font,cellStyleMap.get("yellow")); + setCellValue("所在报文位置", row4.createCell(10), font,cellStyleMap.get("yellow")); + } + + XSSFRow row5 = sheet.createRow(4); + setCellValue("输入", row5.createCell(0), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(1), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(2), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(3), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(4), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(5), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(6), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(7), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(8), font,cellStyleMap.get("green")); + setCellValue("", row5.createCell(9), font,cellStyleMap.get("green")); + if(!isHead){ + setCellValue("", row5.createCell(10), font,cellStyleMap.get("green")); + } + + XSSFRow row6 = sheet.createRow(5); + setCellValue("", row6.createCell(0), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(1), font,cellStyleMap.get("default")); + setCellValue("请输入STRING(具体长度) 或 ARRAY", row6.createCell(2), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(3), font,cellStyleMap.get("default")); + if(isHead){ + setCellValue("", row6.createCell(4), font,cellStyleMap.get("pop")); + setCellValue("", row6.createCell(5), font,cellStyleMap.get("default")); + setCellValue("请输入STRING(具体长度) 或 ARRAY", row6.createCell(6), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(9), font,cellStyleMap.get("default")); + }else { + setCellValue("", row6.createCell(4), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(5), font,cellStyleMap.get("pop")); + setCellValue("", row6.createCell(6), font,cellStyleMap.get("default")); + setCellValue("请输入STRING(具体长度) 或 ARRAY", row6.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(9), font,cellStyleMap.get("default")); + setCellValue("", row6.createCell(10), font,cellStyleMap.get("default")); + } + + + XSSFRow row7 = sheet.createRow(6); + setCellValue("", row7.createCell(1), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(2), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(3), font,cellStyleMap.get("default")); + if(isHead){ + setCellValue("", row7.createCell(4), font,cellStyleMap.get("pop")); + setCellValue("", row7.createCell(5), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(6), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(9), font,cellStyleMap.get("default")); + }else { + setCellValue("", row7.createCell(4), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(5), font,cellStyleMap.get("pop")); + setCellValue("", row7.createCell(6), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(9), font,cellStyleMap.get("default")); + setCellValue("", row7.createCell(10), font,cellStyleMap.get("default")); + } + + + XSSFRow row8 = sheet.createRow(7); + setCellValue("输出", row8.createCell(0), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(1), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(2), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(3), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(4), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(5), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(6), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(7), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(8), font,cellStyleMap.get("green")); + setCellValue("", row8.createCell(9), font,cellStyleMap.get("green")); + if(!isHead){ + setCellValue("", row8.createCell(10), font,cellStyleMap.get("green")); + } + + + XSSFRow row9 = sheet.createRow(8); + setCellValue("", row9.createCell(0), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(1), font,cellStyleMap.get("default")); + setCellValue("请输入STRING(具体长度) 或 ARRAY", row9.createCell(2), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(3), font,cellStyleMap.get("default")); + if(isHead){ + setCellValue("", row9.createCell(4), font,cellStyleMap.get("pop")); + setCellValue("", row9.createCell(5), font,cellStyleMap.get("default")); + setCellValue("请输入STRING(具体长度) 或 ARRAY", row9.createCell(6), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(9), font,cellStyleMap.get("default")); + }else { + setCellValue("", row9.createCell(4), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(5), font,cellStyleMap.get("pop")); + setCellValue("", row9.createCell(6), font,cellStyleMap.get("default")); + setCellValue("请输入STRING(具体长度) 或 ARRAY", row9.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(7), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(8), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(9), font,cellStyleMap.get("default")); + setCellValue("", row9.createCell(10), font,cellStyleMap.get("default")); + } + + } + + private static void setCellValue(String textValue, Cell cell, XSSFFont font,XSSFCellStyle cellStyle) { +// HSSFRichTextString richString = new HSSFRichTextString(textValue); + XSSFRichTextString richString = new XSSFRichTextString(textValue); + richString.applyFont(font); + if(cellStyle!=null){ + cell.setCellStyle(cellStyle); + } + cell.setCellValue(richString); + } + + + @Override + public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) throws Exception { + EsbSheetDataStruct esbImportDataStruct = new EsbSheetDataStruct(); + EsbExcelDataStruct excelDataStruct = this.esbImport(source); + + this.projectId = request.getProjectId(); + ApiDefinitionImport definitionImport = this.parseApiDefinitionImport(excelDataStruct, request); + + return definitionImport; + } + + public EsbExcelDataStruct esbImport(InputStream source) throws IOException, InvalidFormatException { + Workbook workbook = WorkbookFactory.create(source); + int sheetCount = workbook.getNumberOfSheets(); + EsbSheetDataStruct headStruct = null; + List interfaceStruct = new ArrayList<>(); + if (sheetCount > 0) { + Sheet headSheet = workbook.getSheetAt(0); + headStruct = this.parseExcelSheet(headSheet, true); + for (int index = 1; index < sheetCount; index++) { + Sheet dataSheet = workbook.getSheetAt(index); + EsbSheetDataStruct bodyStruct = this.parseExcelSheet(dataSheet, false); + interfaceStruct.add(bodyStruct); + } + } + + EsbExcelDataStruct excelData = new EsbExcelDataStruct(); + excelData.setHeadData(headStruct); + excelData.setInterfaceList(interfaceStruct); + return excelData; + } + + private EsbSheetDataStruct parseExcelSheet(Sheet headSheet, boolean isHeadSheet) { + EsbSheetDataStruct importDataStruct = new EsbSheetDataStruct(); + if (headSheet == null) { + return importDataStruct; + } + int simpleCodeIndex = 0; + int simpleNameIndex = 1; + int apiNameIndex = 6; + int apiDescIndex = 7; + int chineNameIndex = 8; + int descIndex = 9; + int apiPositionIndex = 10; + int cellCount = 11; + if(isHeadSheet){ + apiNameIndex = 5; + apiDescIndex = 6; + chineNameIndex = 7; + descIndex = 8; + apiPositionIndex = 9; + cellCount = 10; + } + + int rowCount = headSheet.getLastRowNum(); + //根据模版样式,如果不是报文头,则要取接口信息 + if (!isHeadSheet) { + Row interfaceInfoRow = headSheet.getRow(1); + if (interfaceInfoRow != null) { + List rowDataArr = this.getRowDataByStartIndexAndEndIndex(interfaceInfoRow, 0, cellCount-1); + if (rowDataArr.size() >= cellCount) { + String interfaceCode = rowDataArr.get(simpleCodeIndex); + String interfaceName = rowDataArr.get(apiNameIndex); + String interfaceDesc = rowDataArr.get(apiDescIndex); + if (StringUtils.isEmpty(interfaceName)) { + interfaceName = rowDataArr.get(simpleNameIndex); + } + importDataStruct.setInterfaceInfo(interfaceCode, interfaceName, interfaceDesc); + } + } + } + //超过5行为空白,直接退出。 + //部分office/wpf生成的文件会出现几万多空行,容易造成内存溢出。这里进行判断,连续五行为空白时认为读取结束。 + int blankRowCount = 0; + boolean isRequest = true; + for (int startRow = REQUEST_MESSAGE_ROW; startRow < rowCount; startRow++) { + Row row = headSheet.getRow(startRow); + List rowDataArr = this.getRowDataByStartIndexAndEndIndex(row, 0, cellCount-1); + boolean isBlankRow = this.checkBlankRow(rowDataArr, cellCount); + if (!isBlankRow) { + String cellFlag = rowDataArr.get(0); + if (StringUtils.equals(cellFlag, "输出")) { + isRequest = false; + } + } + if (isBlankRow) { + if (isRequest) { + isRequest = false; + } + blankRowCount++; + if (blankRowCount > 5) { + break; + } + } else { + blankRowCount = 0; + EsbDataStruct dataStruct = new EsbDataStruct(); + boolean initDataSuccess = dataStruct.initDefaultData(rowDataArr.get(apiNameIndex), rowDataArr.get(apiDescIndex), rowDataArr.get(chineNameIndex), rowDataArr.get(descIndex)); + if (!initDataSuccess) { + continue; + } + boolean isHead = isHeadSheet; + if (rowDataArr.size() > cellCount) { + if (StringUtils.equals(rowDataArr.get(apiPositionIndex), "SYS_HEAD")) { + isHead = true; + } + + } + if (isRequest) { + if (isHead) { + importDataStruct.getReqHeadList().add(dataStruct); + } else { + importDataStruct.getRequestList().add(dataStruct); + } + } else { + if (isHead) { + importDataStruct.getRspHeadList().add(dataStruct); + } else { + importDataStruct.getResponseList().add(dataStruct); + } + } + } + } + return importDataStruct; + } + + private boolean checkBlankRow(List rowDataArr, int rowCheckLength) { + if (rowDataArr == null || rowDataArr.size() < rowCheckLength) { + return true; + } + for (String str : rowDataArr) { + if (StringUtils.isNotEmpty(str)) { + return false; + } + } + return true; + } + + private List getRowDataByStartIndexAndEndIndex(Row row, int startCell, int endCell) { + List returnArray = new ArrayList<>(); + if (row == null) { + return returnArray; + } + for (int i = startCell; i <= endCell; i++) { + Cell cell = row.getCell(i); + if (cell != null) { + returnArray.add(getCellValue(cell)); + }else { + returnArray.add(""); + } + } + return returnArray; + } + + private String getCellValue(Cell cell) { + String returnCellValue = ""; + int cellType = cell.getCellType(); + switch (cellType) { + case Cell.CELL_TYPE_BLANK: + returnCellValue = ""; + break; + case Cell.CELL_TYPE_BOOLEAN: + returnCellValue = String.valueOf(cell.getBooleanCellValue()); + break; + case Cell.CELL_TYPE_ERROR: + returnCellValue = ""; + break; + case Cell.CELL_TYPE_NUMERIC: + returnCellValue = getValueOfNumericCell(cell); + break; + case Cell.CELL_TYPE_FORMULA: + try { + returnCellValue = getValueOfNumericCell(cell); + } catch (IllegalStateException e) { + try { + returnCellValue = cell.getRichStringCellValue().toString(); + } catch (IllegalStateException e2) { + } + } catch (Exception e) { + e.printStackTrace(); + } + break; + default: + returnCellValue = cell.getRichStringCellValue().getString(); + } + if (returnCellValue == null) { + returnCellValue = ""; + } + return returnCellValue; + } + + private String getValueOfNumericCell(Cell cell) { + Boolean isDate = DateUtil.isCellDateFormatted(cell); + Double d = cell.getNumericCellValue(); + String o = null; + if (isDate) { + o = DateFormat.getDateTimeInstance() + .format(cell.getDateCellValue()); + } else { + o = getRealStringValueOfDouble(d); + } + return o; + } + + // 处理科学计数法与普通计数法的字符串显示,尽最大努力保持精度 + private static String getRealStringValueOfDouble(Double d) { + String doubleStr = d.toString(); + boolean b = doubleStr.contains("E"); + int indexOfPoint = doubleStr.indexOf('.'); + if (b) { + int indexOfE = doubleStr.indexOf('E'); + // 小数部分 + BigInteger xs = new BigInteger(doubleStr.substring(indexOfPoint + + BigInteger.ONE.intValue(), indexOfE)); + // 指数 + int pow = Integer.valueOf(doubleStr.substring(indexOfE + + BigInteger.ONE.intValue())); + int xsLen = xs.toByteArray().length; + int scale = xsLen - pow > 0 ? xsLen - pow : 0; + doubleStr = String.format("%." + scale + "f", d); + } else { + java.util.regex.Pattern p = Pattern.compile(".0$"); + java.util.regex.Matcher m = p.matcher(doubleStr); + if (m.find()) { + doubleStr = doubleStr.replace(".0", ""); + } + } + return doubleStr; + } + + private ApiDefinitionImport parseApiDefinitionImport(EsbExcelDataStruct esbExcelDataStruct, ApiTestImportRequest importRequest) { + ApiDefinitionImport resultModel = new ApiDefinitionImport(); + List apiDataList = new ArrayList<>(); + + ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId()); + EsbSheetDataStruct headSheetData = esbExcelDataStruct.getHeadData(); + List interfaceDataList = esbExcelDataStruct.getInterfaceList(); + List savedNames = new ArrayList<>(); + Map esbApiParams = new HashMap<>(); + for (EsbSheetDataStruct interfaceData : interfaceDataList) { + String reqName = interfaceData.getServiceName(); + if (savedNames.contains(reqName)) { + continue; + } else { + savedNames.add(reqName); + } + + String apiId = UUID.randomUUID().toString(); + ApiDefinitionWithBLOBs apiDefinition = new ApiDefinitionWithBLOBs(); + apiDefinition.setName(reqName); + apiDefinition.setMethod("ESB"); + apiDefinition.setId(apiId); + apiDefinition.setProjectId(this.projectId); + apiDefinition.setRequest(genTCPSampler()); + if (StringUtils.equalsIgnoreCase("schedule", importRequest.getType())) { + apiDefinition.setUserId(importRequest.getUserId()); + } else { + apiDefinition.setUserId(SessionUtils.getUserId()); + } + apiDefinition.setProtocol(RequestType.TCP); + buildModule(parentNode, apiDefinition, null); + apiDataList.add(apiDefinition); + + EsbApiParamsWithBLOBs apiParams = new EsbApiParamsWithBLOBs(); + apiParams.setId(UUID.randomUUID().toString()); + apiParams.setResourceId(apiId); + String reqDataStructStr = generateDataStrcut(headSheetData, interfaceData, true); + String respDataStrutStr = generateDataStrcut(headSheetData, interfaceData, false); + + apiParams.setDataStruct(reqDataStructStr); + apiParams.setResponseDataStruct(respDataStrutStr); + esbApiParams.put(apiId, apiParams); + } + + resultModel.setData(apiDataList); + resultModel.setEsbApiParamsMap(esbApiParams); + + return resultModel; + } + + private String genTCPSampler() { + MsTCPSampler tcpSampler = new MsTCPSampler(); + MsJSR223PreProcessor preProcessor = new MsJSR223PreProcessor(); + tcpSampler.setTcpPreProcessor(preProcessor); + tcpSampler.setProtocol("ESB"); + tcpSampler.setClassname("TCPSampler"); + + return JSON.toJSONString(tcpSampler); + } + + private String generateDataStrcut(EsbSheetDataStruct head, EsbSheetDataStruct body, boolean isRequest) { + EsbDataStruct dataStruct = new EsbDataStruct(); + dataStruct.initDefaultData("SERVICE", null, null, null); + List headList = new ArrayList<>(); + List bodyList = new ArrayList<>(); + if (head != null) { + if (isRequest) { + headList.addAll(head.getReqHeadList()); + bodyList.addAll(head.getRequestList()); + } else { + headList.addAll(head.getRspHeadList()); + bodyList.addAll(head.getResponseList()); + } + } + if (body != null) { + if (isRequest) { + headList.addAll(body.getReqHeadList()); + bodyList.addAll(body.getRequestList()); + } else { + headList.addAll(body.getRspHeadList()); + bodyList.addAll(body.getResponseList()); + } + } + + if (!headList.isEmpty()) { + EsbDataStruct headStruct = new EsbDataStruct(); + headStruct.initDefaultData("SYS_HEAD", null, null, null); + dataStruct.getChildren().add(headStruct); + Map childrenEsbDataStructMap = new HashMap<>(); + //用来判断节点有没有在array节点内 + String lastArrayDataStrcutName = null; + for (EsbDataStruct headData : headList) { + if (StringUtils.equalsIgnoreCase("array", headData.getType())) { + if (lastArrayDataStrcutName == null) { + lastArrayDataStrcutName = headData.getName(); + EsbDataStruct arrayStrcut = new EsbDataStruct(); + arrayStrcut.initDefaultData(headData.getName(), headData.getType(), headData.getContentType(), headData.getDescription()); + headStruct.getChildren().add(arrayStrcut); + childrenEsbDataStructMap.put(lastArrayDataStrcutName, arrayStrcut); + } else { + lastArrayDataStrcutName = null; + } + } else { + if (lastArrayDataStrcutName == null) { + headStruct.getChildren().add(headData); + } else { + EsbDataStruct arrayStrcut = childrenEsbDataStructMap.get(lastArrayDataStrcutName); + if (arrayStrcut != null) { + arrayStrcut.getChildren().add(headData); + } + } + } + } + } + + if (!bodyList.isEmpty()) { + EsbDataStruct bodyStruct = new EsbDataStruct(); + bodyStruct.initDefaultData("SYS_BODY", null, null, null); + dataStruct.getChildren().add(bodyStruct); + Map childrenEsbDataStructMap = new HashMap<>(); + //用来判断节点有没有在array节点内 + String lastArrayDataStrcutName = null; + for (EsbDataStruct bodyData : bodyList) { + if (StringUtils.equalsIgnoreCase("array", bodyData.getType())) { + if (lastArrayDataStrcutName == null) { + lastArrayDataStrcutName = bodyData.getName(); + EsbDataStruct arrayStrcut = new EsbDataStruct(); + arrayStrcut.initDefaultData(bodyData.getName(), bodyData.getType(), bodyData.getContentType(), bodyData.getDescription()); + bodyStruct.getChildren().add(arrayStrcut); + childrenEsbDataStructMap.put(lastArrayDataStrcutName, arrayStrcut); + } else { + lastArrayDataStrcutName = null; + } + } else { + if (lastArrayDataStrcutName == null) { + bodyStruct.getChildren().add(bodyData); + } else { + EsbDataStruct arrayStrcut = childrenEsbDataStructMap.get(lastArrayDataStrcutName); + if (arrayStrcut != null) { + arrayStrcut.getChildren().add(bodyData); + } + } + } + } + } + List list = new ArrayList<>(); + list.add(dataStruct); + return JSONArray.toJSONString(list); + } + +// private void parseParameters(HarRequest harRequest, MsHTTPSamplerProxy request) { +// List queryStringList = harRequest.queryString; +// queryStringList.forEach(harQueryParm -> { +// parseQueryParameters(harQueryParm, request.getArguments()); +// }); +// List harHeaderList = harRequest.headers; +// harHeaderList.forEach(harHeader -> { +// parseHeaderParameters(harHeader, request.getHeaders()); +// }); +// List harCookieList = harRequest.cookies; +// harCookieList.forEach(harCookie -> { +// parseCookieParameters(harCookie, request.getHeaders()); +// }); +// } + + + private String getDefaultStringValue(String val) { + return StringUtils.isBlank(val) ? "" : val; + } + + +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/EsbAbstractParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/EsbAbstractParser.java new file mode 100644 index 0000000000..b049b5bc46 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/EsbAbstractParser.java @@ -0,0 +1,28 @@ +package io.metersphere.api.dto.definition.parse; + + +import io.metersphere.api.parse.ApiImportAbstractParser; +import io.metersphere.base.domain.ApiDefinitionWithBLOBs; +import io.metersphere.base.domain.ApiModule; + +import java.util.List; + +/** + * @author song.tianyang + * @Date 2021/3/10 11:15 上午 + * @Description + */ +public abstract class EsbAbstractParser extends ApiImportAbstractParser { + + protected void buildModule(ApiModule parentModule, ApiDefinitionWithBLOBs apiDefinition, List tags) { + if (tags != null) { + tags.forEach(tag -> { + ApiModule module = ApiDefinitionImportUtil.buildModule(parentModule, tag, this.projectId); + apiDefinition.setModuleId(module.getId()); + }); + }else { + apiDefinition.setModuleId(parentModule.getId()); + } + } + +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/esb/EsbExcelDataStruct.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/esb/EsbExcelDataStruct.java new file mode 100644 index 0000000000..90e238819b --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/esb/EsbExcelDataStruct.java @@ -0,0 +1,19 @@ +package io.metersphere.api.dto.definition.parse.esb; + +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author song.tianyang + * @Date 2021/3/23 12:55 下午 + * @Description + */ +@Getter +@Setter +public class EsbExcelDataStruct { + private EsbSheetDataStruct headData; + private List interfaceList = new ArrayList<>(); +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/esb/EsbSheetDataStruct.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/esb/EsbSheetDataStruct.java new file mode 100644 index 0000000000..6f8899b7a4 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/esb/EsbSheetDataStruct.java @@ -0,0 +1,44 @@ +package io.metersphere.api.dto.definition.parse.esb; + +import io.metersphere.api.dto.automation.EsbDataStruct; +import io.metersphere.commons.exception.MSException; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author song.tianyang + * @Date 2021/3/22 9:42 下午 + * @Description + */ +@Getter +@Setter +public class EsbSheetDataStruct { + private String serviceName; + private String serviceDesc; + private List requestList = new ArrayList<>(); + private List responseList = new ArrayList<>(); + + //单个接口内也可能有报文头中要增加的数据 + private List reqHeadList = new ArrayList<>(); + private List rspHeadList = new ArrayList<>(); + + + public void setInterfaceInfo(String interfaceCode, String interfaceName, String interfaceDesc) { + if(StringUtils.isEmpty(interfaceCode) && StringUtils.isEmpty(interfaceName)){ + MSException.throwException("接口的交易码或服务名称不能都为空"); + } + if(StringUtils.isNotEmpty(interfaceCode)){ + this.serviceName = interfaceCode+":"+interfaceName; + }else { + this.serviceName = interfaceName; + } + if (this.serviceName.endsWith(":")){ + this.serviceName = this.serviceName.substring(0,this.serviceName.length()-1); + } + this.serviceDesc = interfaceDesc; + } +} diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java b/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java index d3017c710a..9619cb4fe9 100644 --- a/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java @@ -1,9 +1,11 @@ package io.metersphere.api.parse; import io.metersphere.api.dto.ApiTestImportRequest; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import java.io.IOException; import java.io.InputStream; public interface ApiImportParser { - T parse(InputStream source, ApiTestImportRequest request); + T parse(InputStream source, ApiTestImportRequest request) throws IOException, InvalidFormatException, Exception; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 1980bbe42c..a6cc7ed85e 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -14,6 +14,7 @@ import io.metersphere.api.dto.definition.parse.Swagger3Parser; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.ScheduleInfoSwaggerUrlRequest; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; +import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult; @@ -343,26 +344,43 @@ public class ApiDefinitionService { private void _importCreate(List sameRequest, ApiDefinitionMapper batchMapper, ApiDefinitionWithBLOBs apiDefinition, ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest, List cases) { if (CollectionUtils.isEmpty(sameRequest)) { - String request = setImportHashTree(apiDefinition); - batchMapper.insert(apiDefinition); - apiDefinition.setRequest(request); - importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, true); + if(StringUtils.equalsIgnoreCase(apiDefinition.getProtocol(),RequestType.HTTP)){ + String request = setImportHashTree(apiDefinition); + batchMapper.insert(apiDefinition); + apiDefinition.setRequest(request); + importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, true); + }else{ + if(StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(),RequestType.TCP)){ + String request = setImportTCPHashTree(apiDefinition); + } + batchMapper.insert(apiDefinition); + } + } else { String originId = apiDefinition.getId(); - //如果存在则修改 - apiDefinition.setId(sameRequest.get(0).getId()); - String request = setImportHashTree(apiDefinition); - apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition); - apiDefinition.setRequest(request); - importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, false); - // 如果是带用例导出,重新设置接口id - if (CollectionUtils.isNotEmpty(cases)) { - cases.forEach(item -> { - if (StringUtils.equals(item.getApiDefinitionId(), originId)) { - item.setApiDefinitionId(apiDefinition.getId()); - } - }); + if(StringUtils.equalsIgnoreCase(apiDefinition.getProtocol(),RequestType.HTTP)){ + //如果存在则修改 + apiDefinition.setId(sameRequest.get(0).getId()); + String request = setImportHashTree(apiDefinition); + apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition); + apiDefinition.setRequest(request); + importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, false); + // 如果是带用例导出,重新设置接口id + if (CollectionUtils.isNotEmpty(cases)) { + cases.forEach(item -> { + if (StringUtils.equals(item.getApiDefinitionId(), originId)) { + item.setApiDefinitionId(apiDefinition.getId()); + } + }); + } + }else { + apiDefinition.setId(sameRequest.get(0).getId()); + if(StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(),RequestType.TCP)){ + String request = setImportTCPHashTree(apiDefinition); + } + apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition); } + } } @@ -374,6 +392,14 @@ public class ApiDefinitionService { apiDefinition.setRequest(JSONObject.toJSONString(msHTTPSamplerProxy)); return request; } + private String setImportTCPHashTree(ApiDefinitionWithBLOBs apiDefinition) { + String request = apiDefinition.getRequest(); + MsTCPSampler tcpSampler = JSONObject.parseObject(request, MsTCPSampler.class); + tcpSampler.setId(apiDefinition.getId()); + tcpSampler.setHashTree(new LinkedList<>()); + apiDefinition.setRequest(JSONObject.toJSONString(tcpSampler)); + return request; + } private void importMsCase(ApiDefinitionImport apiImport, SqlSession sqlSession, ApiTestCaseMapper apiTestCaseMapper) { List cases = apiImport.getCases(); @@ -567,11 +593,40 @@ public class ApiDefinitionService { item.setName(item.getName().substring(0, 255)); } item.setNum(num++); - importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases()); + //如果EsbData需要存储,则需要进行接口是否更新的判断 + if(apiImport.getEsbApiParamsMap()!= null){ + String apiId = item.getId(); + EsbApiParamsWithBLOBs model = apiImport.getEsbApiParamsMap().get(apiId); + importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases()); + if(model!=null){ + apiImport.getEsbApiParamsMap().remove(apiId); + model.setResourceId(item.getId()); + apiImport.getEsbApiParamsMap().put(item.getId(),model); + } + }else { + importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases()); + } if (i % 300 == 0) { sqlSession.flushStatements(); } } + //判断EsbData是否需要存储 + if(apiImport.getEsbApiParamsMap()!= null && apiImport.getEsbApiParamsMap().size() > 0){ + EsbApiParamsMapper esbApiParamsMapper = sqlSession.getMapper(EsbApiParamsMapper.class); + for (EsbApiParamsWithBLOBs model : apiImport.getEsbApiParamsMap().values()) { + EsbApiParamsExample example = new EsbApiParamsExample(); + example.createCriteria().andResourceIdEqualTo(model.getResourceId()); + List exiteModelList = esbApiParamsMapper.selectByExampleWithBLOBs(example); + if(exiteModelList.isEmpty()){ + esbApiParamsMapper.insert(model); + }else{ + model.setId(exiteModelList.get(0).getId()); + esbApiParamsMapper.updateByPrimaryKeyWithBLOBs(model); + } + + } + } + if (!CollectionUtils.isEmpty(apiImport.getCases())) { for (int i = 0; i < apiImport.getCases().size(); i++) { importMsCase(apiImport, sqlSession, apiTestCaseMapper); diff --git a/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java b/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java index a8d38ced9e..09a80dda05 100644 --- a/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java +++ b/backend/src/main/java/io/metersphere/api/service/EsbApiParamService.java @@ -75,7 +75,7 @@ public class EsbApiParamService { kv.setType(request.getType()); kv.setDescription(request.getDescription()); kv.setContentType(request.getContentType()); - kv.setRequired(Boolean.parseBoolean(request.getRequired())); + kv.setRequired(request.isRequired()); returnList.add(kv); if (request.getChildren() != null) { List childValueList = this.genKeyValueByEsbDataStruct(request.getChildren(), itemName); @@ -351,4 +351,5 @@ public class EsbApiParamService { example.createCriteria().andResourceIdIn(apiIds); esbApiParamsMapper.deleteByExample(example); } + } diff --git a/backend/src/main/java/io/metersphere/api/service/EsbImportService.java b/backend/src/main/java/io/metersphere/api/service/EsbImportService.java new file mode 100644 index 0000000000..7c8b0ee971 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/service/EsbImportService.java @@ -0,0 +1,80 @@ +package io.metersphere.api.service; + +import io.metersphere.api.dto.definition.parse.ESBParser; +import io.metersphere.commons.constants.TestCaseConstants; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.user.SessionUser; +import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.excel.domain.UserExcelData; +import io.metersphere.excel.domain.UserExcelDataFactory; +import io.metersphere.excel.utils.EasyExcelExporter; +import io.metersphere.i18n.Translator; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +/** + * @author song.tianyang + * @Date 2021/3/22 7:02 下午 + * @Description + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class EsbImportService { + + public void esbTemplateExport(HttpServletResponse response) { + try { + EasyExcelExporter easyExcelExporter = new EasyExcelExporter(new UserExcelDataFactory().getExcelDataByLocal()); + easyExcelExporter.export(response, generateExportTemplate(), + Translator.get("user_import_template_name"), Translator.get("user_import_template_sheet")); + } catch (Exception e) { + MSException.throwException(e); + } + } + + private List generateExportTemplate() { + List list = new ArrayList<>(); + List types = TestCaseConstants.Type.getValues(); + List methods = TestCaseConstants.Method.getValues(); + SessionUser user = SessionUtils.getUser(); + for (int i = 1; i <= 2; i++) { + UserExcelData data = new UserExcelData(); + data.setId("user_id_" + i); + data.setName(Translator.get("user") + i); + String workspace = ""; + for (int workspaceIndex = 1; workspaceIndex <= i; workspaceIndex++) { + if (workspaceIndex == 1) { + workspace = "workspace" + workspaceIndex; + } else { + workspace = workspace + "\n" + "workspace" + workspaceIndex; + } + } + data.setUserIsAdmin(Translator.get("options_no")); + data.setUserIsTester(Translator.get("options_no")); + data.setUserIsOrgMember(Translator.get("options_no")); + data.setUserIsViewer(Translator.get("options_no")); + data.setUserIsTestManager(Translator.get("options_no")); + data.setUserIsOrgAdmin(Translator.get("options_yes")); + data.setOrgAdminOrganization(workspace); + list.add(data); + } + + list.add(new UserExcelData()); + UserExcelData explain = new UserExcelData(); + explain.setName(Translator.get("do_not_modify_header_order")); + explain.setOrgAdminOrganization("多个工作空间请换行展示"); + list.add(explain); + return list; + } + + public void templateExport(HttpServletResponse response) { + try { + ESBParser.export(response,"EsbTemplate"); + } catch (Exception e) { + MSException.throwException(e); + } + } +} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml index 95189a5806..22a84abd24 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml @@ -36,9 +36,12 @@ SELECT * FROM ( SELECT testCase.testCaseID,testCase.testCaseName AS caseName,testCase.testPlanName AS testPlan ,caseErrorCountData.dataCountNumber AS failureTimes,'apiCase' AS caseType FROM ( - SELECT apiCase.id AS testCaseID,apiCase.`name` AS testCaseName,group_concat(testPlan.`name`) AS testPlanName FROM api_test_case apiCase + SELECT apiCase.id AS testCaseID,apiCase.`name` AS testCaseName,group_concat(testPlan.`name`) AS testPlanName, testPlanCase.update_time as updateTime + FROM api_test_case apiCase + inner join api_definition on api_definition.id = apiCase.api_definition_id INNER JOIN test_plan_api_case testPlanCase ON testPlanCase.api_case_id = apiCase.id INNER JOIN test_plan testPlan ON testPlan.id = testPlanCase.test_plan_id + and api_definition.status != 'Trash' GROUP BY apiCase.id ORDER BY apiCase.create_time DESC )testCase @@ -48,7 +51,7 @@ SELECT id FROM api_test_case WHERE project_id = #{projectId} ) and `status` = 'error' GROUP BY resource_id ) caseErrorCountData ON caseErrorCountData.testCaseID =testCase.testCaseID - WHERE caseErrorCountData.executeTime >= #{startTimestamp} + WHERE testCase.updateTime >= #{startTimestamp} UNION SELECT scene.id AS testCaseID,scene.`name` AS caseName,apiScene.testPlanName AS testPlan,count(report.id) AS failureTimes,'scenario' AS caseType FROM api_scenario_report report diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml index 82948829e2..b23321eba5 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml @@ -387,7 +387,8 @@ union all select tpac.id as s from test_plan_api_case tpac join api_test_case on tpac.api_case_id = api_test_case.id - where tpac.test_plan_id = #{planId} + join api_definition on api_test_case.api_definition_id = api_definition.id + where tpac.test_plan_id = #{planId} and api_definition.status != 'Trash' union all select tplc.id as s from test_plan_load_case tplc join load_test on tplc.load_case_id = load_test.id diff --git a/backend/src/main/java/io/metersphere/commons/constants/ApiImportPlatform.java b/backend/src/main/java/io/metersphere/commons/constants/ApiImportPlatform.java index 95aed8d749..eb22a9b40b 100644 --- a/backend/src/main/java/io/metersphere/commons/constants/ApiImportPlatform.java +++ b/backend/src/main/java/io/metersphere/commons/constants/ApiImportPlatform.java @@ -1,5 +1,5 @@ package io.metersphere.commons.constants; public enum ApiImportPlatform { - Metersphere, Postman, Swagger2, Plugin, Jmeter, Har + Metersphere, Postman, Swagger2, Plugin, Jmeter, Har,ESB } diff --git a/backend/src/main/java/io/metersphere/excel/domain/EsbExcelData.java b/backend/src/main/java/io/metersphere/excel/domain/EsbExcelData.java new file mode 100644 index 0000000000..58d670701d --- /dev/null +++ b/backend/src/main/java/io/metersphere/excel/domain/EsbExcelData.java @@ -0,0 +1,9 @@ +package io.metersphere.excel.domain; + +/** + * @author song.tianyang + * @Date 2021/3/22 7:04 下午 + * @Description + */ +public class EsbExcelData { +} diff --git a/frontend/src/business/components/api/definition/components/import/ApiImport.vue b/frontend/src/business/components/api/definition/components/import/ApiImport.vue index 6ccc97837a..291f056a97 100644 --- a/frontend/src/business/components/api/definition/components/import/ApiImport.vue +++ b/frontend/src/business/components/api/definition/components/import/ApiImport.vue @@ -29,11 +29,17 @@ - + + + {{$t('test_track.case.import.download_template')}} + + =0){ + this.platforms.splice(this.platforms.indexOf(this.postmanPlanform),1); + } + if(swaggerPlanformIndex>=0){ + this.platforms.splice(this.platforms.indexOf(this.swaggerPlanform),1); + } + if(harPlanformIndex>=0){ + this.platforms.splice(this.platforms.indexOf(this.harPlanform),1); + } + if(esbPlanformIndex>=0){ + this.platforms.splice(this.platforms.indexOf(this.esbPlanform),1); + } + if(this.propotal === 'TCP'){ + this.platforms.push(this.esbPlanform); + return true; + }else if(this.propotal === 'HTTP'){ + this.platforms.push(this.postmanPlanform); + this.platforms.push(this.swaggerPlanform); + this.platforms.push(this.harPlanform); + return false; + } + } }, computed: { isSwagger2() { return this.selectedPlatformValue === 'Swagger2'; }, - isHar() { - return this.selectedPlatformValue === 'Har'; + showImportModel() { + return this.selectedPlatformValue != 'Har' && this.selectedPlatformValue != 'ESB'; + }, + showTemplate() { + return this.selectedPlatformValue === 'ESB'; }, isScenarioModel() { return this.model === 'scenario'; @@ -235,6 +284,11 @@ export default { handleRemove(file, fileList) { this.formData.file = undefined; }, + downloadTemplate(){ + if(this.selectedPlatformValue == "ESB"){ + this.$fileDownload('/api/definition/export/esbExcelTemplate'); + } + }, uploadValidate(file, fileList) { let suffix = file.name.substring(file.name.lastIndexOf('.') + 1); if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) { @@ -307,7 +361,7 @@ export default {