后台添加backend-listener
This commit is contained in:
parent
6f64057e3b
commit
56241e6535
|
@ -1,12 +1,15 @@
|
||||||
package io.metersphere;
|
package io.metersphere;
|
||||||
|
|
||||||
|
import io.metersphere.config.KafkaProperties;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||||
|
|
||||||
@SpringBootApplication(exclude = {QuartzAutoConfiguration.class})
|
@SpringBootApplication(exclude = {QuartzAutoConfiguration.class})
|
||||||
@ServletComponentScan
|
@ServletComponentScan
|
||||||
|
@EnableConfigurationProperties(KafkaProperties.class)
|
||||||
public class Application {
|
public class Application {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(Application.class, args);
|
SpringApplication.run(Application.class, args);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package io.metersphere.service;
|
package io.metersphere.commons.utils;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
|
@ -1,7 +1,7 @@
|
||||||
package io.metersphere.config;
|
package io.metersphere.config;
|
||||||
|
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.i18n.I18nManager;
|
import io.metersphere.i18n.I18nManager;
|
||||||
import io.metersphere.service.CommonBeanFactory;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
package io.metersphere.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = KafkaProperties.KAFKA_PREFIX)
|
||||||
|
public class KafkaProperties {
|
||||||
|
public static final String KAFKA_PREFIX = "kafka";
|
||||||
|
|
||||||
|
private String acks;
|
||||||
|
private String topic;
|
||||||
|
private String fields;
|
||||||
|
private String timestamp;
|
||||||
|
private String bootstrapServers;
|
||||||
|
private String sampleFilter;
|
||||||
|
private String testMode;
|
||||||
|
private String parseAllReqHeaders;
|
||||||
|
private String parseAllResHeaders;
|
||||||
|
private String compressionType;
|
||||||
|
private String batchSize;
|
||||||
|
private String clientId;
|
||||||
|
private String connectionsMaxIdleMs;
|
||||||
|
private KafkaProperties.Ssl ssl = new KafkaProperties.Ssl();
|
||||||
|
|
||||||
|
public String getAcks() {
|
||||||
|
return acks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAcks(String acks) {
|
||||||
|
this.acks = acks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFields() {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFields(String fields) {
|
||||||
|
this.fields = fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(String timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBootstrapServers() {
|
||||||
|
return bootstrapServers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBootstrapServers(String bootstrapServers) {
|
||||||
|
this.bootstrapServers = bootstrapServers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSampleFilter() {
|
||||||
|
return sampleFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSampleFilter(String sampleFilter) {
|
||||||
|
this.sampleFilter = sampleFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTestMode() {
|
||||||
|
return testMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTestMode(String testMode) {
|
||||||
|
this.testMode = testMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getCompressionType() {
|
||||||
|
return compressionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompressionType(String compressionType) {
|
||||||
|
this.compressionType = compressionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParseAllReqHeaders() {
|
||||||
|
return parseAllReqHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParseAllReqHeaders(String parseAllReqHeaders) {
|
||||||
|
this.parseAllReqHeaders = parseAllReqHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParseAllResHeaders() {
|
||||||
|
return parseAllResHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParseAllResHeaders(String parseAllResHeaders) {
|
||||||
|
this.parseAllResHeaders = parseAllResHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBatchSize() {
|
||||||
|
return batchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatchSize(String batchSize) {
|
||||||
|
this.batchSize = batchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConnectionsMaxIdleMs() {
|
||||||
|
return connectionsMaxIdleMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnectionsMaxIdleMs(String connectionsMaxIdleMs) {
|
||||||
|
this.connectionsMaxIdleMs = connectionsMaxIdleMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Ssl {
|
||||||
|
private String enabled = "false";
|
||||||
|
private String keyPassword;
|
||||||
|
private String keystoreLocation;
|
||||||
|
private String keystorePassword;
|
||||||
|
private String keystoreType;
|
||||||
|
private String truststoreLocation;
|
||||||
|
private String truststorePassword;
|
||||||
|
private String truststoreType;
|
||||||
|
private String protocol;
|
||||||
|
private String enabledProtocols;
|
||||||
|
private String provider;
|
||||||
|
|
||||||
|
public Ssl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(String enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeyPassword() {
|
||||||
|
return keyPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyPassword(String keyPassword) {
|
||||||
|
this.keyPassword = keyPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeystoreLocation() {
|
||||||
|
return keystoreLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeystoreLocation(String keystoreLocation) {
|
||||||
|
this.keystoreLocation = keystoreLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeystorePassword() {
|
||||||
|
return keystorePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeystorePassword(String keystorePassword) {
|
||||||
|
this.keystorePassword = keystorePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeystoreType() {
|
||||||
|
return keystoreType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeystoreType(String keystoreType) {
|
||||||
|
this.keystoreType = keystoreType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTruststoreLocation() {
|
||||||
|
return truststoreLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTruststoreLocation(String truststoreLocation) {
|
||||||
|
this.truststoreLocation = truststoreLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTruststorePassword() {
|
||||||
|
return truststorePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTruststorePassword(String truststorePassword) {
|
||||||
|
this.truststorePassword = truststorePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTruststoreType() {
|
||||||
|
return truststoreType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTruststoreType(String truststoreType) {
|
||||||
|
this.truststoreType = truststoreType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProtocol() {
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProtocol(String protocol) {
|
||||||
|
this.protocol = protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEnabledProtocols() {
|
||||||
|
return enabledProtocols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabledProtocols(String enabledProtocols) {
|
||||||
|
this.enabledProtocols = enabledProtocols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProvider(String provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ssl getSsl() {
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSsl(Ssl ssl) {
|
||||||
|
this.ssl = ssl;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||||
import io.metersphere.commons.constants.I18nConstants;
|
import io.metersphere.commons.constants.I18nConstants;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
import io.metersphere.service.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import io.metersphere.service.SystemParameterService;
|
import io.metersphere.service.SystemParameterService;
|
||||||
import io.metersphere.user.SessionUtils;
|
import io.metersphere.user.SessionUtils;
|
||||||
|
@ -20,13 +20,12 @@ import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
public class Translator {
|
public class Translator {
|
||||||
|
|
||||||
public static final String PREFIX = "$[{";
|
public static final String PREFIX = "$[{";
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package io.metersphere.parse.xml.reader.jmx;
|
package io.metersphere.parse.xml.reader.jmx;
|
||||||
|
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.config.KafkaProperties;
|
||||||
import io.metersphere.engine.EngineContext;
|
import io.metersphere.engine.EngineContext;
|
||||||
import io.metersphere.parse.xml.reader.DocumentParser;
|
import io.metersphere.parse.xml.reader.DocumentParser;
|
||||||
import org.junit.platform.commons.util.StringUtils;
|
import org.junit.platform.commons.util.StringUtils;
|
||||||
|
@ -25,6 +27,8 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
private final static String CONCURRENCY_THREAD_GROUP = "com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup";
|
private final static String CONCURRENCY_THREAD_GROUP = "com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup";
|
||||||
private final static String VARIABLE_THROUGHPUT_TIMER = "kg.apc.jmeter.timers.VariableThroughputTimer";
|
private final static String VARIABLE_THROUGHPUT_TIMER = "kg.apc.jmeter.timers.VariableThroughputTimer";
|
||||||
private final static String THREAD_GROUP = "ThreadGroup";
|
private final static String THREAD_GROUP = "ThreadGroup";
|
||||||
|
private final static String BACKEND_LISTENER = "BackendListener";
|
||||||
|
|
||||||
private EngineContext context;
|
private EngineContext context;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -78,20 +82,106 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
parseHashTree(ele);
|
parseHashTree(ele);
|
||||||
} else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) {
|
} else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) {
|
||||||
processConcurrencyThreadGroup(ele);
|
processConcurrencyThreadGroup(ele);
|
||||||
processTimer(ele);
|
processCheckoutTimer(ele);
|
||||||
|
processCheckoutBackendListener(ele);
|
||||||
} else if (nodeNameEquals(ele, VARIABLE_THROUGHPUT_TIMER)) {
|
} else if (nodeNameEquals(ele, VARIABLE_THROUGHPUT_TIMER)) {
|
||||||
processVariableThroughputTimer(ele);
|
processVariableThroughputTimer(ele);
|
||||||
} else if (nodeNameEquals(ele, THREAD_GROUP)) {
|
} else if (nodeNameEquals(ele, THREAD_GROUP)) {
|
||||||
processThreadGroup(ele);
|
processThreadGroup(ele);
|
||||||
//
|
//
|
||||||
processConcurrencyThreadGroup(ele);
|
processConcurrencyThreadGroup(ele);
|
||||||
processTimer(ele);
|
processCheckoutTimer(ele);
|
||||||
|
processCheckoutBackendListener(ele);
|
||||||
|
} else if (nodeNameEquals(ele, BACKEND_LISTENER)) {
|
||||||
|
processBackendListener(ele);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processBackendListener(Element backendListener) {
|
||||||
|
KafkaProperties kafkaProperties = CommonBeanFactory.getBean(KafkaProperties.class);
|
||||||
|
Document document = backendListener.getOwnerDocument();
|
||||||
|
// 清空child
|
||||||
|
removeChildren(backendListener);
|
||||||
|
backendListener.appendChild(createStringProp(document, "classname", "io.github.rahulsinghai.jmeter.backendlistener.kafka.KafkaBackendClient"));
|
||||||
|
// elementProp
|
||||||
|
Element elementProp = document.createElement("elementProp");
|
||||||
|
elementProp.setAttribute("name", "arguments");
|
||||||
|
elementProp.setAttribute("elementType", "Arguments");
|
||||||
|
elementProp.setAttribute("guiclass", "ArgumentsPanel");
|
||||||
|
elementProp.setAttribute("testclass", "Arguments");
|
||||||
|
elementProp.setAttribute("enabled", "true");
|
||||||
|
Element collectionProp = document.createElement("collectionProp");
|
||||||
|
collectionProp.setAttribute("name", "Arguments.arguments");
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.acks", kafkaProperties.getAcks()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.bootstrap.servers", kafkaProperties.getBootstrapServers()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.topic", kafkaProperties.getTopic()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.sample.filter", kafkaProperties.getSampleFilter()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.fields", kafkaProperties.getFields()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.test.mode", kafkaProperties.getTestMode()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.parse.all.req.headers", kafkaProperties.getParseAllReqHeaders()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.parse.all.res.headers", kafkaProperties.getParseAllResHeaders()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.timestamp", kafkaProperties.getTimestamp()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.compression.type", kafkaProperties.getCompressionType()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.enabled", kafkaProperties.getSsl().getEnabled()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.key.password", kafkaProperties.getSsl().getKeyPassword()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.keystore.location", kafkaProperties.getSsl().getKeystoreLocation()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.keystore.password", kafkaProperties.getSsl().getKeystorePassword()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.truststore.location", kafkaProperties.getSsl().getTruststoreLocation()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.truststore.password", kafkaProperties.getSsl().getTruststorePassword()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.enabled.protocols", kafkaProperties.getSsl().getEnabledProtocols()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.keystore.type", kafkaProperties.getSsl().getKeystoreType()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.protocol", kafkaProperties.getSsl().getProtocol()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.provider", kafkaProperties.getSsl().getProvider()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.truststore.type", kafkaProperties.getSsl().getTruststoreType()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.batch.size", kafkaProperties.getBatchSize()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.client.id", kafkaProperties.getClientId()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.connections.max.idle.ms", kafkaProperties.getConnectionsMaxIdleMs()));
|
||||||
|
|
||||||
|
elementProp.appendChild(collectionProp);
|
||||||
|
// set elementProp
|
||||||
|
backendListener.appendChild(elementProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element createKafkaProp(Document document, String name, String value) {
|
||||||
|
Element eleProp = document.createElement("elementProp");
|
||||||
|
eleProp.setAttribute("name", name);
|
||||||
|
eleProp.setAttribute("elementType", "Argument");
|
||||||
|
eleProp.appendChild(createStringProp(document, "Argument.name", name));
|
||||||
|
eleProp.appendChild(createStringProp(document, "Argument.value", value));
|
||||||
|
eleProp.appendChild(createStringProp(document, "Argument.metadata", "="));
|
||||||
|
return eleProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processCheckoutBackendListener(Element element) {
|
||||||
|
Document document = element.getOwnerDocument();
|
||||||
|
|
||||||
|
Node listenerParent = element.getNextSibling();
|
||||||
|
while (!(listenerParent instanceof Element)) {
|
||||||
|
listenerParent = listenerParent.getNextSibling();
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList childNodes = listenerParent.getChildNodes();
|
||||||
|
for (int i = 0, l = childNodes.getLength(); i < l; i++) {
|
||||||
|
Node item = childNodes.item(i);
|
||||||
|
if (nodeNameEquals(item, BACKEND_LISTENER)) {
|
||||||
|
// 如果已经存在,不再添加
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add class name
|
||||||
|
Element backendListener = document.createElement(BACKEND_LISTENER);
|
||||||
|
backendListener.setAttribute("guiclass", "BackendListenerGui");
|
||||||
|
backendListener.setAttribute("testclass", "BackendListener");
|
||||||
|
backendListener.setAttribute("testname", "Backend Listener");
|
||||||
|
backendListener.setAttribute("enabled", "true");
|
||||||
|
listenerParent.appendChild(backendListener);
|
||||||
|
listenerParent.appendChild(document.createElement(HASH_TREE_ELEMENT));
|
||||||
|
}
|
||||||
|
|
||||||
private void processThreadGroup(Element threadGroup) {
|
private void processThreadGroup(Element threadGroup) {
|
||||||
// 重命名 tagName
|
// 重命名 tagName
|
||||||
Document document = threadGroup.getOwnerDocument();
|
Document document = threadGroup.getOwnerDocument();
|
||||||
|
@ -128,7 +218,7 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
threadGroup.appendChild(createStringProp(document, "Unit", "S"));
|
threadGroup.appendChild(createStringProp(document, "Unit", "S"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processTimer(Element element) {
|
private void processCheckoutTimer(Element element) {
|
||||||
/*
|
/*
|
||||||
<kg.apc.jmeter.timers.VariableThroughputTimer guiclass="kg.apc.jmeter.timers.VariableThroughputTimerGui" testclass="kg.apc.jmeter.timers.VariableThroughputTimer" testname="jp@gc - Throughput Shaping Timer" enabled="true">
|
<kg.apc.jmeter.timers.VariableThroughputTimer guiclass="kg.apc.jmeter.timers.VariableThroughputTimerGui" testclass="kg.apc.jmeter.timers.VariableThroughputTimer" testname="jp@gc - Throughput Shaping Timer" enabled="true">
|
||||||
<collectionProp name="load_profile">
|
<collectionProp name="load_profile">
|
||||||
|
@ -148,6 +238,15 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
timerParent = timerParent.getNextSibling();
|
timerParent = timerParent.getNextSibling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeList childNodes = timerParent.getChildNodes();
|
||||||
|
for (int i = 0, l = childNodes.getLength(); i < l; i++) {
|
||||||
|
Node item = childNodes.item(i);
|
||||||
|
if (nodeNameEquals(item, VARIABLE_THROUGHPUT_TIMER)) {
|
||||||
|
// 如果已经存在,不再添加
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Element timer = document.createElement(VARIABLE_THROUGHPUT_TIMER);
|
Element timer = document.createElement(VARIABLE_THROUGHPUT_TIMER);
|
||||||
timer.setAttribute("guiclass", VARIABLE_THROUGHPUT_TIMER + "Gui");
|
timer.setAttribute("guiclass", VARIABLE_THROUGHPUT_TIMER + "Gui");
|
||||||
timer.setAttribute("testclass", VARIABLE_THROUGHPUT_TIMER);
|
timer.setAttribute("testclass", VARIABLE_THROUGHPUT_TIMER);
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
package io.metersphere;
|
package io.metersphere;
|
||||||
|
|
||||||
|
import io.metersphere.config.KafkaProperties;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.platform.commons.util.StringUtils;
|
import org.junit.platform.commons.util.StringUtils;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
|
@ -18,16 +23,27 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
public class JmxFileParseTest {
|
public class JmxFileParseTest {
|
||||||
private final static String HASH_TREE_ELEMENT = "hashTree";
|
private final static String HASH_TREE_ELEMENT = "hashTree";
|
||||||
private final static String STRING_PROP = "stringProp";
|
private final static String STRING_PROP = "stringProp";
|
||||||
private final static String CONCURRENCY_THREAD_GROUP = "com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup";
|
private final static String CONCURRENCY_THREAD_GROUP = "com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup";
|
||||||
private final static String VARIABLE_THROUGHPUT_TIMER = "kg.apc.jmeter.timers.VariableThroughputTimer";
|
private final static String VARIABLE_THROUGHPUT_TIMER = "kg.apc.jmeter.timers.VariableThroughputTimer";
|
||||||
|
private final static String BACKEND_LISTENER = "BackendListener";
|
||||||
private final static String THREAD_GROUP = "ThreadGroup";
|
private final static String THREAD_GROUP = "ThreadGroup";
|
||||||
|
@Resource
|
||||||
|
private KafkaProperties kafkaProperties;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperties() {
|
||||||
|
System.out.println(kafkaProperties.getSsl());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parse() throws Exception {
|
public void parse() throws Exception {
|
||||||
File file = new File("/Users/liuruibin/Downloads/blaze_meter_dev2.jmx");
|
File file = new File("/Users/liuruibin/Downloads/blaze_meter_dev2.jmx");
|
||||||
|
file = new File("/Users/liuruibin/Desktop/test-jmeter.jmx");
|
||||||
|
|
||||||
final FileInputStream inputStream = new FileInputStream(file);
|
final FileInputStream inputStream = new FileInputStream(file);
|
||||||
final InputSource inputSource = new InputSource(inputStream);
|
final InputSource inputSource = new InputSource(inputStream);
|
||||||
|
@ -80,19 +96,104 @@ public class JmxFileParseTest {
|
||||||
parseHashTree(ele);
|
parseHashTree(ele);
|
||||||
} else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) {
|
} else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) {
|
||||||
processConcurrencyThreadGroup(ele);
|
processConcurrencyThreadGroup(ele);
|
||||||
processTimer(ele);
|
processCheckoutTimer(ele);
|
||||||
|
processCheckoutBackendListener(ele);
|
||||||
} else if (nodeNameEquals(ele, THREAD_GROUP)) {
|
} else if (nodeNameEquals(ele, THREAD_GROUP)) {
|
||||||
processThreadGroup(ele);
|
processThreadGroup(ele);
|
||||||
processConcurrencyThreadGroup(ele);
|
processConcurrencyThreadGroup(ele);
|
||||||
processTimer(ele);
|
processCheckoutTimer(ele);
|
||||||
|
processCheckoutBackendListener(ele);
|
||||||
} else if (nodeNameEquals(ele, VARIABLE_THROUGHPUT_TIMER)) {
|
} else if (nodeNameEquals(ele, VARIABLE_THROUGHPUT_TIMER)) {
|
||||||
|
|
||||||
|
} else if (nodeNameEquals(ele, BACKEND_LISTENER)) {
|
||||||
|
processBackendListener(ele);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processBackendListener(Element backendListener) {
|
||||||
|
Document document = backendListener.getOwnerDocument();
|
||||||
|
// 清空child
|
||||||
|
removeChildren(backendListener);
|
||||||
|
backendListener.appendChild(createStringProp(document, "classname", "io.github.rahulsinghai.jmeter.backendlistener.kafka.KafkaBackendClient"));
|
||||||
|
// elementProp
|
||||||
|
Element elementProp = document.createElement("elementProp");
|
||||||
|
elementProp.setAttribute("name", "arguments");
|
||||||
|
elementProp.setAttribute("elementType", "Arguments");
|
||||||
|
elementProp.setAttribute("guiclass", "ArgumentsPanel");
|
||||||
|
elementProp.setAttribute("testclass", "Arguments");
|
||||||
|
elementProp.setAttribute("enabled", "true");
|
||||||
|
Element collectionProp = document.createElement("collectionProp");
|
||||||
|
collectionProp.setAttribute("name", "Arguments.arguments");
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.acks", kafkaProperties.getAcks()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.bootstrap.servers", kafkaProperties.getBootstrapServers()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.topic", kafkaProperties.getTopic()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.sample.filter", kafkaProperties.getSampleFilter()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.fields", kafkaProperties.getFields()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.test.mode", kafkaProperties.getTestMode()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.parse.all.req.headers", kafkaProperties.getParseAllReqHeaders()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.parse.all.res.headers", kafkaProperties.getParseAllResHeaders()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.timestamp", kafkaProperties.getTimestamp()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.compression.type", kafkaProperties.getCompressionType()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.enabled", kafkaProperties.getSsl().getEnabled()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.key.password", kafkaProperties.getSsl().getKeyPassword()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.keystore.location", kafkaProperties.getSsl().getKeystoreLocation()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.keystore.password", kafkaProperties.getSsl().getKeystorePassword()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.truststore.location", kafkaProperties.getSsl().getTruststoreLocation()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.truststore.password", kafkaProperties.getSsl().getTruststorePassword()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.enabled.protocols", kafkaProperties.getSsl().getEnabledProtocols()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.keystore.type", kafkaProperties.getSsl().getKeystoreType()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.protocol", kafkaProperties.getSsl().getProtocol()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.provider", kafkaProperties.getSsl().getProvider()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.ssl.truststore.type", kafkaProperties.getSsl().getTruststoreType()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.batch.size", kafkaProperties.getBatchSize()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.client.id", kafkaProperties.getClientId()));
|
||||||
|
collectionProp.appendChild(createKafkaProp(document, "kafka.connections.max.idle.ms", kafkaProperties.getConnectionsMaxIdleMs()));
|
||||||
|
|
||||||
|
elementProp.appendChild(collectionProp);
|
||||||
|
// set elementProp
|
||||||
|
backendListener.appendChild(elementProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processCheckoutBackendListener(Element element) {
|
||||||
|
Document document = element.getOwnerDocument();
|
||||||
|
|
||||||
|
Node listenerParent = element.getNextSibling();
|
||||||
|
while (!(listenerParent instanceof Element)) {
|
||||||
|
listenerParent = listenerParent.getNextSibling();
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList childNodes = listenerParent.getChildNodes();
|
||||||
|
for (int i = 0, l = childNodes.getLength(); i < l; i++) {
|
||||||
|
Node item = childNodes.item(i);
|
||||||
|
if (nodeNameEquals(item, BACKEND_LISTENER)) {
|
||||||
|
// 如果已经存在,不再添加
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add class name
|
||||||
|
Element backendListener = document.createElement(BACKEND_LISTENER);
|
||||||
|
backendListener.setAttribute("guiclass", "BackendListenerGui");
|
||||||
|
backendListener.setAttribute("testclass", "BackendListener");
|
||||||
|
backendListener.setAttribute("testname", "Backend Listener");
|
||||||
|
backendListener.setAttribute("enabled", "true");
|
||||||
|
listenerParent.appendChild(backendListener);
|
||||||
|
listenerParent.appendChild(document.createElement(HASH_TREE_ELEMENT));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element createKafkaProp(Document document, String name, String value) {
|
||||||
|
Element eleProp = document.createElement("elementProp");
|
||||||
|
eleProp.setAttribute("name", name);
|
||||||
|
eleProp.setAttribute("elementType", "Argument");
|
||||||
|
eleProp.appendChild(createStringProp(document, "Argument.name", name));
|
||||||
|
eleProp.appendChild(createStringProp(document, "Argument.value", value));
|
||||||
|
eleProp.appendChild(createStringProp(document, "Argument.metadata", "="));
|
||||||
|
return eleProp;
|
||||||
|
}
|
||||||
|
|
||||||
private void processThreadGroup(Element threadGroup) {
|
private void processThreadGroup(Element threadGroup) {
|
||||||
// 重命名 tagName
|
// 重命名 tagName
|
||||||
Document document = threadGroup.getOwnerDocument();
|
Document document = threadGroup.getOwnerDocument();
|
||||||
|
@ -128,7 +229,7 @@ public class JmxFileParseTest {
|
||||||
threadGroup.appendChild(createStringProp(document, "Unit", "S"));
|
threadGroup.appendChild(createStringProp(document, "Unit", "S"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processTimer(Element element) {
|
private void processCheckoutTimer(Element element) {
|
||||||
/*
|
/*
|
||||||
<kg.apc.jmeter.timers.VariableThroughputTimer guiclass="kg.apc.jmeter.timers.VariableThroughputTimerGui" testclass="kg.apc.jmeter.timers.VariableThroughputTimer" testname="jp@gc - Throughput Shaping Timer" enabled="true">
|
<kg.apc.jmeter.timers.VariableThroughputTimer guiclass="kg.apc.jmeter.timers.VariableThroughputTimerGui" testclass="kg.apc.jmeter.timers.VariableThroughputTimer" testname="jp@gc - Throughput Shaping Timer" enabled="true">
|
||||||
<collectionProp name="load_profile">
|
<collectionProp name="load_profile">
|
||||||
|
@ -148,6 +249,15 @@ public class JmxFileParseTest {
|
||||||
timerParent = timerParent.getNextSibling();
|
timerParent = timerParent.getNextSibling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeList childNodes = timerParent.getChildNodes();
|
||||||
|
for (int i = 0, l = childNodes.getLength(); i < l; i++) {
|
||||||
|
Node item = childNodes.item(i);
|
||||||
|
if (nodeNameEquals(item, VARIABLE_THROUGHPUT_TIMER)) {
|
||||||
|
// 如果已经存在,不再添加
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Element timer = document.createElement(VARIABLE_THROUGHPUT_TIMER);
|
Element timer = document.createElement(VARIABLE_THROUGHPUT_TIMER);
|
||||||
timer.setAttribute("guiclass", VARIABLE_THROUGHPUT_TIMER + "Gui");
|
timer.setAttribute("guiclass", VARIABLE_THROUGHPUT_TIMER + "Gui");
|
||||||
timer.setAttribute("testclass", VARIABLE_THROUGHPUT_TIMER);
|
timer.setAttribute("testclass", VARIABLE_THROUGHPUT_TIMER);
|
||||||
|
@ -164,6 +274,8 @@ public class JmxFileParseTest {
|
||||||
collectionProp.appendChild(childCollectionProp);
|
collectionProp.appendChild(childCollectionProp);
|
||||||
timer.appendChild(collectionProp);
|
timer.appendChild(collectionProp);
|
||||||
timerParent.appendChild(timer);
|
timerParent.appendChild(timer);
|
||||||
|
// 添加一个空的hashTree
|
||||||
|
timerParent.appendChild(document.createElement(HASH_TREE_ELEMENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element createStringProp(Document document, String name, String value) {
|
private Element createStringProp(Document document, String name, String value) {
|
||||||
|
|
Loading…
Reference in New Issue