fix(系统设置): 修复历史jar无法删除的缺陷

https://github.com/metersphere/metersphere/issues/21122
This commit is contained in:
wxg0103 2023-01-05 17:45:21 +08:00 committed by wxg0103
parent 37bf87f8ac
commit 662787156d
5 changed files with 89 additions and 21 deletions

View File

@ -2,14 +2,9 @@ package io.metersphere.controller;
import io.metersphere.api.dto.plugin.PluginDTO;
import io.metersphere.api.dto.plugin.PluginRequest;
import io.metersphere.service.PluginService;
import io.metersphere.base.domain.Plugin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.metersphere.service.PluginService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@ -21,8 +16,8 @@ public class PluginController {
private PluginService pluginService;
@GetMapping("/list")
public List<PluginDTO> list(String name) {
return pluginService.list(name);
public List<PluginDTO> list() {
return pluginService.getPluginList();
}
@GetMapping("/get/{id}")

View File

@ -88,7 +88,7 @@ public class PluginService {
public void loadPlugins() {
try {
PluginExample example = new PluginExample();
example.createCriteria().andScenarioEqualTo(PluginScenario.api.name());
example.createCriteria().andScenarioNotEqualTo(PluginScenario.platform.name());
List<Plugin> plugins = pluginMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(plugins)) {
plugins = plugins.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
@ -109,15 +109,11 @@ public class PluginService {
}
}
public List<PluginDTO> list(String name) {
public List<PluginDTO> getPluginList() {
List<PluginDTO> lists = new LinkedList<>();
try {
PluginExample example = new PluginExample();
example.createCriteria().andScenarioEqualTo(PluginScenario.api.name());
if (StringUtils.isNotBlank(name)) {
name = "%" + name + "%";
example.createCriteria().andNameLike(name);
}
example.createCriteria().andScenarioNotEqualTo(PluginScenario.platform.name());
List<Plugin> plugins = pluginMapper.selectByExample(example);
Map<String, Boolean> pluginMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(plugins)) {
@ -183,7 +179,7 @@ public class PluginService {
public List<Plugin> list() {
PluginExample example = new PluginExample();
example.createCriteria().andScenarioEqualTo(PluginScenario.api.name());
example.createCriteria().andScenarioNotEqualTo(PluginScenario.platform.name());
List<Plugin> plugins = pluginMapper.selectByExample(example);
return plugins;
}

View File

@ -2,6 +2,7 @@ package io.metersphere.listener;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.service.PlatformPluginService;
import io.metersphere.service.PluginService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@ -13,10 +14,15 @@ public class InitListener implements ApplicationRunner {
@Resource
private PlatformPluginService platformPluginService;
@Resource
private PluginService pluginService;
@Override
public void run(ApplicationArguments applicationArguments) {
LogUtil.info("================= SYSTEM-SETTING 应用启动 =================");
pluginService.loadPlugins();
platformPluginService.loadPlatFormPlugins();
}
}

View File

@ -20,13 +20,18 @@ import io.metersphere.metadata.vo.FileRequest;
import io.metersphere.request.PluginDTO;
import io.metersphere.request.PluginRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
@ -63,7 +68,7 @@ public class PluginService {
plugins.forEach(item -> {
PluginDTO dto = new PluginDTO();
BeanUtils.copyBean(dto, item);
if (StringUtils.equals(PluginScenario.api.name(), item.getScenario())) {
if (!StringUtils.equals(PluginScenario.platform.name(), item.getScenario())) {
// api 插件调用
if (!pluginMap.containsKey(item.getPluginId())) {
dto.setLicense(apiPluginService.isXpack(item));
@ -154,6 +159,72 @@ public class PluginService {
}
}
public void loadPlugins() {
try {
PluginExample example = new PluginExample();
example.createCriteria().andScenarioNotEqualTo(PluginScenario.platform.name());
List<Plugin> plugins = pluginMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(plugins)) {
plugins = plugins.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
-> new TreeSet<>(Comparator.comparing(Plugin::getPluginId))), ArrayList::new));
if (CollectionUtils.isNotEmpty(plugins)) {
plugins.forEach(item -> {
boolean isLoad = this.loadJar(item.getSourcePath(), item.getPluginId());
if (!isLoad) {
PluginExample pluginExample = new PluginExample();
pluginExample.createCriteria().andPluginIdEqualTo(item.getPluginId());
pluginMapper.deleteByExample(pluginExample);
}
});
}
}
} catch (Exception e) {
LogUtil.error(e);
}
}
private boolean loadJar(String jarPath, String pluginId) {
try {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try {
File file = new File(jarPath);
if (!file.exists()) {
// 从MinIO下载
if (!this.downPluginJar(jarPath, pluginId, jarPath)) {
return false;
}
}
if (!file.exists()) {
return false;
}
Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(classLoader, file.toURI().toURL());
} catch (NoSuchMethodException e) {
Method method = classLoader.getClass()
.getDeclaredMethod("appendToClassPathForInstrumentation", String.class);
method.setAccessible(true);
method.invoke(classLoader, jarPath);
}
return true;
} catch (Exception e) {
LogUtil.error(e);
}
return false;
}
private boolean downPluginJar(String path, String pluginId, String jarPath) {
FileRequest request = new FileRequest();
request.setProjectId(StringUtils.join(FileUtils.BODY_FILE_DIR, "/plugin", pluginId));
request.setFileName(pluginId);
request.setStorage(StorageConstants.MINIO.name());
byte[] bytes = fileManagerService.downloadFile(request);
if (ArrayUtils.isNotEmpty(bytes)) {
FileUtils.createFile(path, bytes);
}
return new File(jarPath).exists();
}
public String getLogDetails(String id) {
PluginExample example = new PluginExample();
example.createCriteria().andPluginIdEqualTo(id);

View File

@ -107,7 +107,7 @@ export default {
this.format(res.data);
this.dataMap.forEach((values, key) => {
let item = values[0];
if (item.scenario === 'api') {
if (item.scenario !== 'platform') {
let obj = {};
Object.assign(obj, item);
obj.id = key;
@ -141,9 +141,9 @@ export default {
this.$refs.scriptView.open(row.scriptId);
},
handleDelete(row) {
let tip = row.scenario === 'api' ? this.$t('api_test.jar_config.delete_tip') : this.$t('api_test.jar_config.delete_confirm');
let tip = row.scenario !== 'platform' ? this.$t('api_test.jar_config.delete_tip') : this.$t('api_test.jar_config.delete_confirm');
operationConfirm(this, tip, () => {
this.loading = delPluginById(row.scenario, row.id).then(() => {
this.loading = delPluginById(row.scenario || 'api', row.id).then(() => {
this.$success(this.$t('commons.delete_success'));
this.initPlugins();
});