feat (插件管理): 增加xpack插件校验

This commit is contained in:
fit2-zhao 2021-09-14 19:28:03 +08:00 committed by fit2-zhao
parent 069c747ab8
commit 2a37568338
7 changed files with 84 additions and 20 deletions

View File

@ -2,6 +2,7 @@ package io.metersphere.controller;
import io.metersphere.base.domain.Plugin;
import io.metersphere.commons.exception.MSException;
import io.metersphere.controller.request.PluginDTO;
import io.metersphere.controller.request.PluginRequest;
import io.metersphere.service.PluginService;
import org.springframework.web.bind.annotation.*;
@ -26,7 +27,7 @@ public class PluginController {
}
@GetMapping("/list")
public List<Plugin> list() {
public List<PluginDTO> list() {
return pluginService.list();
}

View File

@ -0,0 +1,9 @@
package io.metersphere.controller.request;
import io.metersphere.base.domain.Plugin;
import lombok.Data;
@Data
public class PluginDTO extends Plugin {
private Boolean license;
}

View File

@ -8,11 +8,11 @@ import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.FileUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.PluginDTO;
import io.metersphere.controller.request.PluginRequest;
import io.metersphere.controller.request.PluginResourceDTO;
import io.metersphere.plugin.core.ui.PluginResource;
import io.metersphere.service.utils.CommonUtil;
import io.metersphere.service.utils.MsClassLoader;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -32,8 +32,6 @@ import java.util.stream.Collectors;
public class PluginService {
@Resource
private PluginMapper pluginMapper;
@Resource
private MsClassLoader classLoader;
public String editPlugin(MultipartFile file) {
String id = UUID.randomUUID().toString();
@ -79,6 +77,15 @@ public class PluginService {
});
}
private boolean isXpack(Class<?> aClass, Object instance) {
try {
Object verify = aClass.getDeclaredMethod("xpack").invoke(instance);
return (Boolean) verify;
} catch (Exception e) {
return false;
}
}
private List<PluginResourceDTO> getMethod(String path, String fileName) {
List<PluginResourceDTO> resources = new LinkedList<>();
try {
@ -143,10 +150,30 @@ public class PluginService {
}
}
public List<Plugin> list() {
public List<PluginDTO> list() {
PluginExample example = new PluginExample();
List<Plugin> plugins = pluginMapper.selectByExample(example);
return plugins;
Map<String, Boolean> pluginMap = new HashMap<>();
List<PluginDTO> lists = new LinkedList<>();
// 校验插件是否是企业版
plugins.forEach(item -> {
PluginDTO dto = new PluginDTO();
BeanUtils.copyBean(dto, item);
if (!pluginMap.containsKey(item.getPluginId())) {
try {
Class<?> clazz = Class.forName(item.getExecEntry());
Object instance = clazz.newInstance();
dto.setLicense(this.isXpack(Class.forName(item.getExecEntry()), instance));
} catch (Exception e) {
LogUtil.error(e.getMessage());
}
} else {
dto.setLicense(pluginMap.get(item.getPluginId()));
}
lists.add(dto);
pluginMap.put(item.getPluginId(), dto.getLicense());
});
return lists;
}
public Plugin get(String scriptId) {

View File

@ -332,7 +332,7 @@ import {
strMapToObj,
handleCtrlSEvent,
getCurrentProjectID,
handleCtrlREvent
handleCtrlREvent, hasLicense
} from "@/common/js/utils";
import "@/common/css/material-icons.css"
import OutsideClick from "@/common/js/outside-click";
@ -529,8 +529,20 @@ export default {
},
getPlugins() {
let url = "/plugin/list";
this.plugins = [];
this.$get(url, response => {
this.plugins = response.data;
let data = response.data;
if (data) {
data.forEach(item => {
if (item.license) {
if (hasLicense()) {
this.plugins.push(item);
}
} else {
this.plugins.push(item);
}
})
}
});
},
stop() {

View File

@ -150,7 +150,7 @@
import {API_STATUS, PRIORITY} from "../../../definition/model/JsonData";
import {parseEnvironment} from "../../../definition/model/EnvironmentModel";
import {ELEMENT_TYPE, STEP} from "../Setting";
import {getCurrentProjectID, getUUID, strMapToObj} from "@/common/js/utils";
import {getCurrentProjectID, getUUID, hasLicense, strMapToObj} from "@/common/js/utils";
import "@/common/css/material-icons.css"
import OutsideClick from "@/common/js/outside-click";
import {handleCtrlSEvent} from "../../../../../../common/js/utils";
@ -293,8 +293,16 @@ export default {
this.addComponent(item.name, item)
}
}
if (this.operatingElements && this.operatingElements.includes(item.jmeterClazz)) {
this.buttonData.push(plugin);
if (item.license) {
if (hasLicense()) {
if (this.operatingElements && this.operatingElements.includes(item.jmeterClazz)) {
this.buttonData.push(plugin);
}
}
} else {
if (this.operatingElements && this.operatingElements.includes(item.jmeterClazz)) {
this.buttonData.push(plugin);
}
}
});
}
@ -704,7 +712,7 @@ export default {
this.$refs['currentScenario'].validate((valid) => {
if (valid) {
this.setParameter();
saveScenario(this.path, this.currentScenario, this.scenarioDefinition, this,(response) => {
saveScenario(this.path, this.currentScenario, this.scenarioDefinition, this, (response) => {
this.$success(this.$t('commons.save_success'));
this.path = "/api/automation/update";
if (response.data) {

View File

@ -30,6 +30,12 @@
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column prop="license" :label="$t('license.licenseVersion')">
<template v-slot:default="scope">
<span v-if="scope.row.license">企业版</span>
<span v-else>开源版</span>
</template>
</el-table-column>
<el-table-column :label="$t('commons.operating')" min-width="30">
<template v-slot:default="scope">
<div v-if="scope.row.name === scope.row.sourceName">
@ -94,7 +100,7 @@ export default {
if (response.data) {
this.format(response.data);
this.dataMap.forEach((values, key) => {
let obj = {id: key, name: values[0].sourceName, sourceName: values[0].sourceName, pluginId: key, createUserId: values[0].createUserId, updateTime: values[0].updateTime};
let obj = {id: key, license: values[0].license, name: values[0].sourceName, sourceName: values[0].sourceName, pluginId: key, createUserId: values[0].createUserId, updateTime: values[0].updateTime};
obj.children = values;
this.tableData.push(obj);
})

View File

@ -143,7 +143,7 @@ export function hasPermission(permission) {
export function hasLicense() {
let v = localStorage.getItem(LicenseKey);
return v === 'valid';
return v && v === 'valid';
}
export function hasRolePermissions(...roles) {
@ -253,15 +253,16 @@ export function mapToJson(strMap) {
export function humpToLine(name) {
return name.replace(/([A-Z])/g, "_$1").toLowerCase();
}
// 下划线转换驼峰
export function lineToHump(name) {
return name.replace(/\_(\w)/g, function(all, letter){
return name.replace(/\_(\w)/g, function (all, letter) {
return letter.toUpperCase();
});
}
// 查找字符出现的次数
export function getCharCountInStr(str, char){
export function getCharCountInStr(str, char) {
if (!str) return 0;
let regex = new RegExp(char, 'g'); // 使用g表示整个字符串都要匹配
let result = str.match(regex);
@ -544,7 +545,7 @@ export function stopFullScreenLoading(loading, timeout) {
export function getShareId() {
//let herfUrl = 'http://localhost:8080/sharePlanReport?shareId=bf9496ac-8577-46b4-adf9-9c7e93dd06a8';
let herfUrl = window.location.href;
let herfUrl = window.location.href;
if (herfUrl.indexOf('shareId=') > -1) {
let shareId = '';
new URL(herfUrl).searchParams.forEach((value, key) => {
@ -554,11 +555,11 @@ export function getShareId() {
});
return shareId;
} else {
if(herfUrl.indexOf("?") > 0){
if (herfUrl.indexOf("?") > 0) {
let paramArr = herfUrl.split("?");
if(paramArr.length > 1){
if (paramArr.length > 1) {
let shareId = paramArr[1];
if(shareId.indexOf("#") > 0){
if (shareId.indexOf("#") > 0) {
shareId = shareId.split("#")[0];
}
return shareId;