refactor(性能测试): 重构性能测试解析jmx的方式
This commit is contained in:
parent
ff664cd1b9
commit
285ca02ba1
|
@ -8,7 +8,7 @@ public class EngineContext {
|
|||
private String testName;
|
||||
private String namespace;
|
||||
private String fileType;
|
||||
private String content;
|
||||
private byte[] content;
|
||||
private String resourcePoolId;
|
||||
private String reportId;
|
||||
private Integer resourceIndex;
|
||||
|
@ -52,11 +52,11 @@ public class EngineContext {
|
|||
return this.properties.get(key);
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
public void setContent(byte[] content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,25 +25,15 @@ import org.apache.commons.beanutils.ConstructorUtils;
|
|||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.reflections8.Reflections;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -239,7 +229,7 @@ public class EngineFactory {
|
|||
engineContext.setTestResourceFiles(testResourceFiles);
|
||||
|
||||
try (ByteArrayInputStream source = new ByteArrayInputStream(jmxBytes)) {
|
||||
String content = engineSourceParser.parse(engineContext, source);
|
||||
byte[] content = engineSourceParser.parse(engineContext, source);
|
||||
engineContext.setContent(content);
|
||||
} catch (MSException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
|
@ -309,80 +299,75 @@ public class EngineFactory {
|
|||
return props.toString().getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] mergeJmx(List<FileMetadata> jmxFiles) {
|
||||
try {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Element hashTree = null;
|
||||
Document rootDocument = null;
|
||||
for (FileMetadata fileMetadata : jmxFiles) {
|
||||
FileContent fileContent = fileService.getFileContent(fileMetadata.getId());
|
||||
final InputSource inputSource = new InputSource(new ByteArrayInputStream(fileContent.getFile()));
|
||||
InputStream inputSource = new ByteArrayInputStream(fileContent.getFile());
|
||||
if (hashTree == null) {
|
||||
rootDocument = docBuilder.parse(inputSource);
|
||||
Element jmeterTestPlan = rootDocument.getDocumentElement();
|
||||
NodeList childNodes = jmeterTestPlan.getChildNodes();
|
||||
rootDocument = EngineSourceParserFactory.getDocument(inputSource);
|
||||
Element jmeterTestPlan = rootDocument.getRootElement();
|
||||
List<Element> childNodes = jmeterTestPlan.elements();
|
||||
|
||||
outer:
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node instanceof Element) {
|
||||
for (Element node : childNodes) {
|
||||
// jmeterTestPlan的子元素肯定是<hashTree></hashTree>
|
||||
NodeList childNodes1 = node.getChildNodes();
|
||||
for (int j = 0; j < childNodes1.getLength(); j++) {
|
||||
Node item = childNodes1.item(j);
|
||||
if (StringUtils.equalsIgnoreCase("hashTree", item.getNodeName())) {
|
||||
hashTree = (Element) node;
|
||||
List<Element> childNodes1 = node.elements();
|
||||
for (Element item : childNodes1) {
|
||||
if (StringUtils.equalsIgnoreCase("TestPlan", item.getName())) {
|
||||
hashTree = getNextSibling(item);
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Document document = docBuilder.parse(inputSource);
|
||||
Element jmeterTestPlan = document.getDocumentElement();
|
||||
NodeList childNodes = jmeterTestPlan.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node instanceof Element) {
|
||||
Document document = EngineSourceParserFactory.getDocument(inputSource);
|
||||
Element jmeterTestPlan = document.getRootElement();
|
||||
List<Element> childNodes = jmeterTestPlan.elements();
|
||||
for (Element node : childNodes) {
|
||||
// jmeterTestPlan的子元素肯定是<hashTree></hashTree>
|
||||
Element secondHashTree = (Element) node;
|
||||
NodeList secondChildNodes = secondHashTree.getChildNodes();
|
||||
for (int j = 0; j < secondChildNodes.getLength(); j++) {
|
||||
Node item = secondChildNodes.item(j);
|
||||
if (StringUtils.equalsIgnoreCase("TestPlan", item.getNodeName())) {
|
||||
continue;
|
||||
Element secondHashTree = node;
|
||||
List<Element> secondChildNodes = secondHashTree.elements();
|
||||
for (Element item : secondChildNodes) {
|
||||
if (StringUtils.equalsIgnoreCase("TestPlan", item.getName())) {
|
||||
secondHashTree = getNextSibling(item);
|
||||
break;
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase("hashTree", item.getNodeName())) {
|
||||
NodeList itemChildNodes = item.getChildNodes();
|
||||
for (int k = 0; k < itemChildNodes.getLength(); k++) {
|
||||
Node item1 = itemChildNodes.item(k);
|
||||
Node newNode = item1.cloneNode(true);
|
||||
rootDocument.adoptNode(newNode);
|
||||
hashTree.appendChild(newNode);
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase("hashTree", secondHashTree.getName())) {
|
||||
List<Element> itemChildNodes = secondHashTree.elements();
|
||||
for (Element item1 : itemChildNodes) {
|
||||
hashTree.add((Element) item1.clone());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
inputSource.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return documentToBytes(rootDocument);
|
||||
return EngineSourceParserFactory.formatXml(rootDocument);
|
||||
} catch (Exception e) {
|
||||
MSException.throwException(e);
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
private static byte[] documentToBytes(Document document) throws TransformerException {
|
||||
DOMSource domSource = new DOMSource(document);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamResult result = new StreamResult(out);
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer transformer = tf.newTransformer();
|
||||
transformer.transform(domSource, result);
|
||||
return out.toByteArray();
|
||||
private static Element getNextSibling(Element ele) {
|
||||
Element parent = ele.getParent();
|
||||
if (parent != null) {
|
||||
Iterator<Element> iterator = parent.elementIterator();
|
||||
while (iterator.hasNext()) {
|
||||
Element next = iterator.next();
|
||||
if (ele.equals(next)) {
|
||||
return iterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Resource
|
||||
|
|
|
@ -5,5 +5,5 @@ import io.metersphere.performance.engine.EngineContext;
|
|||
import java.io.InputStream;
|
||||
|
||||
public interface EngineSourceParser {
|
||||
String parse(EngineContext context, InputStream source) throws Exception;
|
||||
byte[] parse(EngineContext context, InputStream source) throws Exception;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,96 @@
|
|||
package io.metersphere.performance.parse;
|
||||
|
||||
import io.metersphere.commons.constants.FileType;
|
||||
import io.metersphere.performance.parse.xml.XmlEngineSourceParse;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.performance.parse.xml.reader.JmeterDocumentParser;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.dom4j.io.XMLWriter;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class EngineSourceParserFactory {
|
||||
public static final boolean IS_TRANS = true;
|
||||
|
||||
|
||||
public static EngineSourceParser createEngineSourceParser(String type) {
|
||||
final FileType engineType = FileType.valueOf(type);
|
||||
|
||||
if (FileType.JMX.equals(engineType)) {
|
||||
return new XmlEngineSourceParse();
|
||||
return new JmeterDocumentParser();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Document getDocument(InputStream source) throws DocumentException {
|
||||
SAXReader reader = new SAXReader();
|
||||
if (!IS_TRANS) {
|
||||
reader.setXMLFilter(EngineSourceParserFactory.getFilter());
|
||||
}
|
||||
return reader.read(source);
|
||||
}
|
||||
|
||||
public static byte[] formatXml(Document document) throws Exception {
|
||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||
try (
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
) {
|
||||
XMLWriter xw = new XMLWriter(out, format);
|
||||
xw.setEscapeText(IS_TRANS);
|
||||
xw.write(document);
|
||||
xw.flush();
|
||||
xw.close();
|
||||
return out.toByteArray();
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public static XMLFilterImpl getFilter() {
|
||||
return new XMLFilterImpl() {
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
String text = new String(ch, start, length);
|
||||
|
||||
if (length == 1) {
|
||||
if (StringUtils.equals("&", text)) {
|
||||
char[] escape = "&".toCharArray();
|
||||
super.characters(escape, start, escape.length);
|
||||
return;
|
||||
}
|
||||
if (StringUtils.equals("\"", text)) {
|
||||
char[] escape = """.toCharArray();
|
||||
super.characters(escape, start, escape.length);
|
||||
return;
|
||||
}
|
||||
if (StringUtils.equals("'", text)) {
|
||||
char[] escape = "'".toCharArray();
|
||||
super.characters(escape, start, escape.length);
|
||||
return;
|
||||
}
|
||||
if (StringUtils.equals("<", text)) {
|
||||
char[] escape = "<".toCharArray();
|
||||
super.characters(escape, start, escape.length);
|
||||
return;
|
||||
}
|
||||
if (StringUtils.equals(">", text)) {
|
||||
char[] escape = ">".toCharArray();
|
||||
super.characters(escape, start, escape.length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.characters(ch, start, length);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package io.metersphere.performance.parse.xml;
|
||||
|
||||
import io.metersphere.performance.engine.EngineContext;
|
||||
import io.metersphere.performance.parse.EngineSourceParser;
|
||||
import io.metersphere.performance.parse.xml.reader.DocumentParser;
|
||||
import io.metersphere.performance.parse.xml.reader.DocumentParserFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class XmlEngineSourceParse implements EngineSourceParser {
|
||||
@Override
|
||||
public String parse(EngineContext context, InputStream source) throws Exception {
|
||||
final InputSource inputSource = new InputSource(source);
|
||||
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
final Document document = docBuilder.parse(inputSource);
|
||||
|
||||
final DocumentParser documentParser = createDocumentParser(context.getFileType());
|
||||
|
||||
return documentParser.parse(context, document);
|
||||
}
|
||||
|
||||
private DocumentParser createDocumentParser(String type) {
|
||||
return DocumentParserFactory.createDocumentParser(type);
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package io.metersphere.performance.parse.xml.reader;
|
||||
|
||||
import io.metersphere.performance.engine.EngineContext;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
public interface DocumentParser {
|
||||
String parse(EngineContext context, Document document) throws Exception;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package io.metersphere.performance.parse.xml.reader;
|
||||
|
||||
import io.metersphere.commons.constants.FileType;
|
||||
import io.metersphere.performance.parse.xml.reader.jmx.JmeterDocumentParser;
|
||||
|
||||
public class DocumentParserFactory {
|
||||
public static DocumentParser createDocumentParser(String type) {
|
||||
final FileType fileType = FileType.valueOf(type);
|
||||
|
||||
switch (fileType) {
|
||||
case JMX:
|
||||
return new JmeterDocumentParser();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,6 @@ import org.springframework.stereotype.Service;
|
|||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -60,11 +59,11 @@ public class JmeterFileService {
|
|||
Map<String, byte[]> files = new HashMap<>();
|
||||
|
||||
// 每个测试生成一个文件夹
|
||||
files.put(fileName, context.getContent().getBytes(StandardCharsets.UTF_8));
|
||||
files.put(fileName, context.getContent());
|
||||
// 保存jmx
|
||||
LoadTestReportWithBLOBs record = new LoadTestReportWithBLOBs();
|
||||
record.setId(context.getReportId());
|
||||
record.setJmxContent(context.getContent());
|
||||
record.setJmxContent(new String(context.getContent()));
|
||||
extLoadTestReportMapper.updateJmxContentIfAbsent(record);
|
||||
// 保存 byte[]
|
||||
Map<String, byte[]> jarFiles = context.getTestResourceFiles();
|
||||
|
|
Loading…
Reference in New Issue