feat(接口测试): 加载接口插件时注册组件解析器

This commit is contained in:
AgAngle 2024-02-06 21:27:13 +08:00 committed by Craftsman
parent 1e026eebc0
commit b8065a64d6
10 changed files with 103 additions and 23 deletions

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.request.http.body; package io.metersphere.api.dto.request.http.body;
import io.metersphere.api.dto.ApiFile; import io.metersphere.api.dto.ApiFile;
import jakarta.validation.Valid;
import lombok.Data; import lombok.Data;
/** /**
@ -9,9 +10,14 @@ import lombok.Data;
* @CreateTime: 2023-11-06 18:25 * @CreateTime: 2023-11-06 18:25
*/ */
@Data @Data
public class BinaryBody extends ApiFile { public class BinaryBody {
/** /**
* 描述 * 描述
*/ */
private String description; private String description;
/**
* 文件对象
*/
@Valid
private ApiFile file;
} }

View File

@ -14,7 +14,7 @@ import org.apache.jmeter.protocol.http.util.HTTPFileArg;
public class MsBinaryBodyConverter extends MsBodyConverter<BinaryBody> { public class MsBinaryBodyConverter extends MsBodyConverter<BinaryBody> {
@Override @Override
public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) { public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) {
HTTPFileArg httpFileArg = getHttpFileArg(body); HTTPFileArg httpFileArg = getHttpFileArg(body.getFile());
sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg}); sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg});
} }
} }

View File

@ -0,0 +1,41 @@
package io.metersphere.api.service;
import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.api.utils.JmeterElementConverterRegister;
import io.metersphere.plugin.api.spi.AbstractApiPlugin;
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
import io.metersphere.plugin.api.spi.JmeterElementConverter;
import io.metersphere.plugin.api.spi.MsTestElement;
import io.metersphere.sdk.plugin.MsPluginManager;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.service.PluginChangeService;
import io.metersphere.system.service.PluginLoadService;
import org.pf4j.Plugin;
import org.springframework.stereotype.Service;
/**
* @Author: jianxing
* @CreateTime: 2024-02-06 20:55
*/
@Service
public class ApiPluginChangeService implements PluginChangeService {
@Override
public void handlePluginLoad(String pluginId) {
MsPluginManager msPluginManager = CommonBeanFactory.getBean(PluginLoadService.class).getMsPluginManager();
Plugin plugin = msPluginManager.getPlugin(pluginId).getPlugin();
try {
if (plugin instanceof AbstractApiPlugin) {
// 注册序列化类
msPluginManager.getExtensionClasses(MsTestElement.class, pluginId)
.forEach(ApiDataUtils::setResolver);
// 注册插件元素解析器
msPluginManager.getExtensionClasses(JmeterElementConverter.class, pluginId)
.forEach(item -> JmeterElementConverterRegister.register((Class<? extends AbstractJmeterElementConverter<? extends MsTestElement>>) item));
}
} catch (Exception e) {
LogUtils.error("注册接口插件实现类失败:", e);
}
}
}

View File

@ -17,10 +17,6 @@ import io.metersphere.api.service.definition.ApiDefinitionService;
import io.metersphere.api.service.definition.ApiTestCaseService; import io.metersphere.api.service.definition.ApiTestCaseService;
import io.metersphere.api.service.scenario.ApiScenarioService; import io.metersphere.api.service.scenario.ApiScenarioService;
import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.api.utils.JmeterElementConverterRegister;
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
import io.metersphere.plugin.api.spi.JmeterElementConverter;
import io.metersphere.plugin.api.spi.MsTestElement;
import io.metersphere.project.api.assertion.MsResponseCodeAssertion; import io.metersphere.project.api.assertion.MsResponseCodeAssertion;
import io.metersphere.project.api.assertion.MsScriptAssertion; import io.metersphere.project.api.assertion.MsScriptAssertion;
import io.metersphere.project.api.processor.MsProcessor; import io.metersphere.project.api.processor.MsProcessor;
@ -660,15 +656,6 @@ public class ApiScenarioControllerTests extends BaseTest {
request.getStepDetails().put(pluginStep.getId(), pluginStepDetail); request.getStepDetails().put(pluginStep.getId(), pluginStepDetail);
Plugin plugin = addEnvTestPlugin(); Plugin plugin = addEnvTestPlugin();
List<Class<? extends MsTestElement>> msTestElementClasses =
pluginLoadService.getMsPluginManager().getExtensionClasses(MsTestElement.class);
// 注册序列化类
msTestElementClasses.forEach(ApiDataUtils::setResolver);
// 注册转换器
List<Class<? extends JmeterElementConverter>> converterClasses =
pluginLoadService.getMsPluginManager().getExtensionClasses(JmeterElementConverter.class);
converterClasses.forEach(item -> JmeterElementConverterRegister.register((Class<? extends AbstractJmeterElementConverter<? extends MsTestElement>>) item));
this.requestPostWithOk(DEBUG, request); this.requestPostWithOk(DEBUG, request);
pluginService.delete(plugin.getId()); pluginService.delete(plugin.getId());

View File

@ -102,7 +102,9 @@ public class MsHTTPElementTest {
xmlBody.setValue("<a/>"); xmlBody.setValue("<a/>");
body.setXmlBody(xmlBody); body.setXmlBody(xmlBody);
body.setBinaryBody(BeanUtils.copyBean(new BinaryBody(), bodyFile)); BinaryBody binaryBody = new BinaryBody();
binaryBody.setFile(bodyFile);
body.setBinaryBody(binaryBody);
return body; return body;
} }

View File

@ -1,12 +1,12 @@
package io.metersphere.api.controller; package io.metersphere.api.controller;
import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.jsontype.NamedType;
import io.metersphere.api.dto.request.controller.MsLoopController;
import io.metersphere.api.dto.request.http.MsHTTPElement;
import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.plugin.api.dto.TestElementDTO; import io.metersphere.plugin.api.dto.TestElementDTO;
import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.plugin.api.spi.MsTestElement; import io.metersphere.plugin.api.spi.MsTestElement;
import io.metersphere.api.dto.request.http.MsHTTPElement;
import io.metersphere.api.dto.request.controller.MsLoopController;
import io.metersphere.system.base.BaseApiPluginTestService; import io.metersphere.system.base.BaseApiPluginTestService;
import io.metersphere.system.service.PluginLoadService; import io.metersphere.system.service.PluginLoadService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;

View File

@ -0,0 +1,27 @@
package io.metersphere.system.invoker;
import io.metersphere.system.service.PluginChangeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @Author: jianxing
* @CreateTime: 2024-02-06 20:48
*/
@Component
public class PluginChangeServiceInvoker implements PluginChangeService {
private final List<PluginChangeService> pluginChangeServices;
@Autowired
public PluginChangeServiceInvoker(List<PluginChangeService> services) {
this.pluginChangeServices = services;
}
@Override
public void handlePluginLoad(String pluginId) {
this.pluginChangeServices.forEach(service -> service.handlePluginLoad(pluginId));
}
}

View File

@ -0,0 +1,13 @@
package io.metersphere.system.service;
/**
* @Author: jianxing
* @CreateTime: 2024-02-06 20:47
*/
public interface PluginChangeService {
/**
* 插件时调用
* @param pluginId 插件ID
*/
void handlePluginLoad(String pluginId);
}

View File

@ -15,6 +15,7 @@ import io.metersphere.sdk.util.MsFileUtils;
import io.metersphere.system.domain.Plugin; import io.metersphere.system.domain.Plugin;
import io.metersphere.system.domain.PluginExample; import io.metersphere.system.domain.PluginExample;
import io.metersphere.system.domain.PluginScript; import io.metersphere.system.domain.PluginScript;
import io.metersphere.system.invoker.PluginChangeServiceInvoker;
import io.metersphere.system.mapper.PluginMapper; import io.metersphere.system.mapper.PluginMapper;
import io.metersphere.system.mapper.PluginScriptMapper; import io.metersphere.system.mapper.PluginScriptMapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -49,6 +50,8 @@ public class PluginLoadService {
private PluginMapper pluginMapper; private PluginMapper pluginMapper;
@Resource @Resource
private PluginScriptMapper pluginScriptMapper; private PluginScriptMapper pluginScriptMapper;
@Resource
private PluginChangeServiceInvoker pluginChangeServiceInvoker;
private MsPluginManager msPluginManager = new MsPluginManager(); private MsPluginManager msPluginManager = new MsPluginManager();
/** /**
@ -65,7 +68,11 @@ public class PluginLoadService {
// 文件不存在则从对象存储重新下载 // 文件不存在则从对象存储重新下载
downloadPluginFromRepository(fileName); downloadPluginFromRepository(fileName);
} }
return msPluginManager.loadPlugin(Paths.get(filePath)); String pluginId = msPluginManager.loadPlugin(Paths.get(filePath));
msPluginManager.startPlugin(pluginId);
// 通知其他服务处理插件加载逻辑
pluginChangeServiceInvoker.handlePluginLoad(pluginId);
return pluginId;
} }
@ -83,7 +90,7 @@ public class PluginLoadService {
if (!file.exists()) { if (!file.exists()) {
try (InputStream fileAsStream = FileCenter.getDefaultRepository().getFileAsStream(getDefaultRepositoryFileRequest(fileName))) { try (InputStream fileAsStream = FileCenter.getDefaultRepository().getFileAsStream(getDefaultRepositoryFileRequest(fileName))) {
FileUtils.copyInputStreamToFile(fileAsStream, file); FileUtils.copyInputStreamToFile(fileAsStream, file);
msPluginManager.loadPlugin(Paths.get(filePath)); loadPlugin(filePath);
} catch (Exception e) { } catch (Exception e) {
LogUtils.error("从对象存储加载插件异常", e); LogUtils.error("从对象存储加载插件异常", e);
} }
@ -192,7 +199,6 @@ public class PluginLoadService {
String fileName = plugin.getFileName(); String fileName = plugin.getFileName();
try { try {
loadPlugin(fileName); loadPlugin(fileName);
msPluginManager.startPlugin(plugin.getId());
} catch (Throwable e) { } catch (Throwable e) {
LogUtils.error("初始化插件异常" + plugin.getFileName(), e); LogUtils.error("初始化插件异常" + plugin.getFileName(), e);
} }
@ -308,7 +314,6 @@ public class PluginLoadService {
public void handlePluginAddNotified(String pluginId, String fileName) { public void handlePluginAddNotified(String pluginId, String fileName) {
if (!hasPlugin(pluginId)) { if (!hasPlugin(pluginId)) {
loadPluginFromRepository(fileName); loadPluginFromRepository(fileName);
msPluginManager.startPlugin(pluginId);
} }
} }

View File

@ -117,7 +117,6 @@ public class PluginService {
// 从文件系统中加载插件 // 从文件系统中加载插件
id = pluginLoadService.loadPlugin(file.getOriginalFilename()); id = pluginLoadService.loadPlugin(file.getOriginalFilename());
pluginLoadService.getMsPluginManager().startPlugin(id);
plugin.setId(id); plugin.setId(id);
List<Driver> extensions = pluginLoadService.getMsPluginManager().getExtensions(Driver.class, id); List<Driver> extensions = pluginLoadService.getMsPluginManager().getExtensions(Driver.class, id);