add plugin sdk

This commit is contained in:
fit2-zhao 2023-04-14 17:13:25 +08:00
parent 2c20f999b7
commit 29ff912f9d
10 changed files with 507 additions and 2 deletions

View File

@ -0,0 +1 @@
公共插件包,定义执行数据的基类和公共接口

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.metersphere</groupId>
<artifactId>framework</artifactId>
<version>${revision}</version>
</parent>
<groupId>io.metersphere</groupId>
<artifactId>plugin-sdk</artifactId>
<version>${revision}</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<name>plugin-sdk</name>
<description>MeterSphere plugin</description>
<dependencies>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>${jmeter.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,18 @@
package io.metersphere.plugin.api.api;
import io.metersphere.plugin.api.dto.ApiPluginDTO;
public abstract class ApiPluginService {
/**
* 初始化页面脚本
* 上传JAR到MeterSphere平台后会自动调用
*/
public abstract ApiPluginDTO init();
/**
* 自定义方法用于在自定义插件中初始化数据
* @return 返回要处理的JSON数据
*/
public abstract String custom(String... args);
}

View File

@ -0,0 +1,25 @@
package io.metersphere.plugin.api.dto;
import lombok.Data;
import java.util.List;
@Data
public class ApiPluginDTO {
/**
* jar唯一标识且不变每次上传jar通过它更新
*/
private String pluginId;
/**
* UI脚本一个UI步骤一条
*/
private List<ScriptDTO> uiScripts;
public ApiPluginDTO() {
}
public ApiPluginDTO(String pluginId, List<ScriptDTO> uiScripts) {
this.pluginId = pluginId;
this.uiScripts = uiScripts;
}
}

View File

@ -0,0 +1,7 @@
package io.metersphere.plugin.api.dto;
/**
* 公共传递参数基类
*/
public class BaseConfigDTO {
}

View File

@ -0,0 +1,66 @@
package io.metersphere.plugin.api.dto;
import lombok.Data;
@Data
public class ScriptDTO {
/**
* 脚本唯一标识
*/
private String id;
/**
* 显示名称
*/
private String name;
/**
* 这个参数非常重要对应继承 MsTestElement的类全名
* io.xx.MsThriftSample
*/
private String clazzName;
/**
* 插件实现的jmeter基类
* 请求的基类
*/
private String jmeterClazz;
/**
* 表单基本参数
* 这个可选/不填走默认值
*/
private String formOption;
/**
* 表单脚本内容
*/
private String formScript;
public ScriptDTO() {
}
public ScriptDTO(String id, String name, String clazzName, String script) {
this.id = id;
this.name = name;
this.clazzName = clazzName;
this.formScript = script;
}
public ScriptDTO(String id, String name, String clazzName, String script, String option) {
this.id = id;
this.name = name;
this.clazzName = clazzName;
this.formScript = script;
this.formOption = option;
}
public ScriptDTO(String id, String name, String clazzName, String jmeterClazz, String script, String option) {
this.id = id;
this.name = name;
this.clazzName = clazzName;
this.jmeterClazz = jmeterClazz;
this.formScript = script;
this.formOption = option;
}
}

View File

@ -0,0 +1,85 @@
package io.metersphere.plugin.api.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.metersphere.plugin.util.LogUtil;
import lombok.Data;
import org.apache.jmeter.save.SaveService;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree;
import java.io.ByteArrayOutputStream;
import java.util.LinkedList;
import java.util.List;
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "clazzName")
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class TestElementDTO {
// 组件类型
private String type;
// 用于数据反射对象
private String clazzName = TestElementDTO.class.getCanonicalName();
// 当前组件唯一标示
private String resourceId;
// 组件标签名称
private String name;
// 是否展开收起操作
private boolean active;
// 组件索引
private String index;
// 是否禁用/启用标示
private boolean enable = true;
// 子组件
private LinkedList<TestElementDTO> hashTree;
// 父类
private TestElementDTO parent;
/**
* 公共环境逐层传递如果自身有环境 以自身引用环境为准否则以公共环境作为请求环境
*/
public void toHashTree(HashTree tree, List<TestElementDTO> hashTree, BaseConfigDTO config) {
if (hashTree != null && !hashTree.isEmpty()) {
for (TestElementDTO el : hashTree) {
el.toHashTree(tree, el.hashTree, config);
}
}
}
/**
* 转换JMX
*
* @param hashTree
* @return
*/
public String getJmx(HashTree hashTree) {
try (ByteArrayOutputStream bas = new ByteArrayOutputStream()) {
SaveService.saveTree(hashTree, bas);
return bas.toString();
} catch (Exception e) {
e.printStackTrace();
LogUtil.warn("HashTree error, can't log jmx scenarioDefinition");
}
return null;
}
public HashTree generateHashTree(BaseConfigDTO config) {
HashTree jmeterTestPlanHashTree = new ListedHashTree();
this.toHashTree(jmeterTestPlanHashTree, this.hashTree, config);
return jmeterTestPlanHashTree;
}
}

View File

@ -0,0 +1,259 @@
package io.metersphere.plugin.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
public class LogUtil {
public static final String DEBUG = "DEBUG";
public static final String INFO = "INFO";
public static final String WARN = "WARN";
public static final String ERROR = "ERROR";
/**
* 初始化日志
*
* @return
*/
public static Logger getLogger() {
return LoggerFactory.getLogger(LogUtil.getLogClass());
}
public static void writeLog(Object msg, String level) {
Logger logger = LogUtil.getLogger();
if (DEBUG.equals(level)) {
if (logger != null && logger.isDebugEnabled()) {
logger.debug(LogUtil.getMsg(msg));
}
} else if (INFO.equals(level)) {
if (logger != null && logger.isInfoEnabled()) {
logger.info(LogUtil.getMsg(msg));
}
} else if (WARN.equals(level)) {
if (logger != null && logger.isWarnEnabled()) {
logger.warn(LogUtil.getMsg(msg));
}
} else if (ERROR.equals(level)) {
if (logger != null && logger.isErrorEnabled()) {
logger.error(LogUtil.getMsg(msg));
}
} else {
if (logger != null && logger.isErrorEnabled()) {
logger.error("");
}
}
}
public static void info(Object msg) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isInfoEnabled()) {
logger.info(LogUtil.getMsg(msg));
System.out.println(msg);
}
}
public static void info(Object msg, Object o1) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isInfoEnabled()) {
logger.info(LogUtil.getMsg(msg), o1);
}
}
public static void info(Object msg, Object o1, Object o2) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isInfoEnabled()) {
logger.info(LogUtil.getMsg(msg), o1, o2);
}
}
public static void info(Object msg, Object[] obj) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isInfoEnabled()) {
logger.info(LogUtil.getMsg(msg), obj);
}
}
public static void debug(Object msg) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isDebugEnabled()) {
logger.debug(LogUtil.getMsg(msg));
}
}
public static void debug(Object msg, Object o) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isDebugEnabled()) {
logger.debug(LogUtil.getMsg(msg), o);
}
}
public static void debug(Object msg, Object o1, Object o2) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isDebugEnabled()) {
logger.debug(LogUtil.getMsg(msg), o1, o2);
}
}
public static void debug(Object msg, Object[] obj) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isDebugEnabled()) {
logger.debug(LogUtil.getMsg(msg), obj);
}
}
public static void warn(Object msg) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isWarnEnabled()) {
logger.warn(LogUtil.getMsg(msg));
}
}
public static void warn(Object msg, Object o) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isWarnEnabled()) {
logger.warn(LogUtil.getMsg(msg), o);
}
}
public static void warn(Object msg, Object o1, Object o2) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isWarnEnabled()) {
logger.warn(LogUtil.getMsg(msg), o1, o2);
}
}
public static void warn(Object msg, Object[] obj) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isWarnEnabled()) {
logger.warn(LogUtil.getMsg(msg), obj);
}
}
public static void error(Object msg) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isErrorEnabled()) {
logger.error(LogUtil.getMsg(msg));// 并追加方法名称
}
}
public static void error(Object msg, Object o) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isErrorEnabled()) {
logger.error(LogUtil.getMsg(msg), o);
}
}
public static void error(Object msg, Object o1, Object o2) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isErrorEnabled()) {
logger.error(LogUtil.getMsg(msg), o1, o2);
}
}
public static void error(Object msg, Object[] obj) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isErrorEnabled()) {
logger.error(LogUtil.getMsg(msg), obj);
}
}
public static void error(Object msg, Throwable ex) {
Logger logger = LogUtil.getLogger();
if (logger != null && logger.isErrorEnabled()) {
logger.error(LogUtil.getMsg(msg), ex);
}
}
public static String getMsg(Object msg, Throwable ex) {
String str = "";
if (msg != null) {
str = LogUtil.getLogMethod() + "[" + msg.toString() + "]";
} else {
str = LogUtil.getLogMethod() + "[null]";
}
if (ex != null) {
str += "[" + ex.getMessage() + "]";
}
return str;
}
public static String getMsg(Object msg) {
return LogUtil.getMsg(msg, null);
}
/**
* 得到调用类名称
*
* @return
*/
private static String getLogClass() {
String str = "";
StackTraceElement[] stack = (new Throwable()).getStackTrace();
if (stack.length > 3) {
StackTraceElement ste = stack[3];
str = ste.getClassName();// 类名称
}
return str;
}
/**
* 得到调用方法名称
*
* @return
*/
private static String getLogMethod() {
String str = "";
StackTraceElement[] stack = (new Throwable()).getStackTrace();
if (stack.length > 4) {
StackTraceElement ste = stack[4];
str = "Method[" + ste.getMethodName() + "]";// 方法名称
}
return str;
}
public static String toString(Throwable e) {
StringWriter sw = null;
PrintWriter pw = null;
try {
sw = new StringWriter();
pw = new PrintWriter(sw);
//将出错的栈信息输出到printWriter中
e.printStackTrace(pw);
pw.flush();
sw.flush();
} finally {
if (sw != null) {
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (pw != null) {
pw.close();
}
}
return sw.toString();
}
public static String getExceptionDetailsToStr(Exception e) {
StringBuilder sb = new StringBuilder(e.toString());
StackTraceElement[] stackElements = e.getStackTrace();
for (StackTraceElement stackTraceElement : stackElements) {
sb.append(stackTraceElement.toString());
sb.append("\n");
}
sb.append("\n");
return sb.toString();
}
}

View File

@ -14,6 +14,7 @@
<version>${revision}</version>
<modules>
<module>plugin</module>
<module>domain</module>
<module>jmeter</module>
<module>sdk</module>

View File

@ -342,8 +342,8 @@
<!-- 基础包 -->
<dependency>
<groupId>io.metersphere</groupId>
<artifactId>metersphere-plugin-core</artifactId>
<version>${metersphere-plugin-core.version}</version>
<artifactId>plugin-sdk</artifactId>
<version>${version}</version>
<exclusions>
<exclusion>
<artifactId>log4j-slf4j-impl</artifactId>