feat: 开发配额插槽支持自定义配额规则

This commit is contained in:
fit2-zhao 2023-11-09 10:51:36 +08:00 committed by Craftsman
parent 03b1f8c7b4
commit ea1a654c5d
6 changed files with 63 additions and 4 deletions

View File

@ -0,0 +1,7 @@
package io.metersphere.plugin.sdk.spi;
import io.metersphere.plugin.sdk.util.MSPluginException;
public abstract class QuotaPlugin extends AbstractMsPlugin {
public abstract void interceptor(Object pjp) throws MSPluginException;
}

View File

@ -12,5 +12,9 @@ public enum PluginScenarioType {
/** /**
* jdbc 驱动插件 * jdbc 驱动插件
*/ */
JDBC_DRIVER JDBC_DRIVER,
/**
* 配额控制
*/
QUOTA
} }

View File

@ -0,0 +1,32 @@
package io.metersphere.system.config;
import io.metersphere.plugin.sdk.spi.QuotaPlugin;
import io.metersphere.system.service.PluginLoadService;
import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.pf4j.PluginWrapper;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class QuotaInterceptor {
@Resource
private PluginLoadService pluginLoadService;
// 插件ID
private final String QUOTA = "cloud-quota-plugin";
@Around("execution(* io.metersphere..*(..)) && " +
"(@annotation(org.springframework.web.bind.annotation.PostMapping) ||" +
"@annotation(org.springframework.web.bind.annotation.GetMapping)|| " +
"@annotation(org.springframework.web.bind.annotation.RequestMapping))")
public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
// 验证配额规则
PluginWrapper pluginWrapper = pluginLoadService.getMsPluginManager().getPlugin(QUOTA);
if (pluginWrapper != null && pluginWrapper.getPlugin() instanceof QuotaPlugin quotaPlugin) {
quotaPlugin.interceptor(pjp);
}
return pjp.proceed();
}
}

View File

@ -7,9 +7,9 @@ import io.metersphere.plugin.platform.dto.SelectOption;
import io.metersphere.plugin.platform.spi.AbstractPlatformPlugin; import io.metersphere.plugin.platform.spi.AbstractPlatformPlugin;
import io.metersphere.plugin.platform.spi.Platform; import io.metersphere.plugin.platform.spi.Platform;
import io.metersphere.plugin.sdk.spi.MsPlugin; import io.metersphere.plugin.sdk.spi.MsPlugin;
import io.metersphere.plugin.sdk.spi.QuotaPlugin;
import io.metersphere.sdk.constants.KafkaTopicConstants; import io.metersphere.sdk.constants.KafkaTopicConstants;
import io.metersphere.sdk.constants.PluginScenarioType; import io.metersphere.sdk.constants.PluginScenarioType;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
@ -18,10 +18,11 @@ import io.metersphere.system.domain.Plugin;
import io.metersphere.system.domain.PluginExample; import io.metersphere.system.domain.PluginExample;
import io.metersphere.system.dto.PluginDTO; import io.metersphere.system.dto.PluginDTO;
import io.metersphere.system.dto.PluginNotifiedDTO; import io.metersphere.system.dto.PluginNotifiedDTO;
import io.metersphere.system.mapper.ExtPluginMapper;
import io.metersphere.system.mapper.PluginMapper;
import io.metersphere.system.dto.request.PlatformOptionRequest; import io.metersphere.system.dto.request.PlatformOptionRequest;
import io.metersphere.system.dto.request.PluginUpdateRequest; import io.metersphere.system.dto.request.PluginUpdateRequest;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.mapper.ExtPluginMapper;
import io.metersphere.system.mapper.PluginMapper;
import io.metersphere.system.utils.ServiceUtils; import io.metersphere.system.utils.ServiceUtils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@ -165,6 +166,8 @@ public class PluginService {
plugin.setScenario(PluginScenarioType.API_PROTOCOL.name()); plugin.setScenario(PluginScenarioType.API_PROTOCOL.name());
} else if (msPlugin instanceof AbstractPlatformPlugin) { } else if (msPlugin instanceof AbstractPlatformPlugin) {
plugin.setScenario(PluginScenarioType.PLATFORM.name()); plugin.setScenario(PluginScenarioType.PLATFORM.name());
}else if(msPlugin instanceof QuotaPlugin){
plugin.setScenario(PluginScenarioType.QUOTA.name());
} }
plugin.setXpack(msPlugin.isXpack()); plugin.setXpack(msPlugin.isXpack());
plugin.setPluginId(descriptor.getPluginId() + "-" + descriptor.getVersion()); plugin.setPluginId(descriptor.getPluginId() + "-" + descriptor.getVersion());

View File

@ -161,6 +161,19 @@ public class PluginControllerTests extends BaseTest {
getDefaultMultiPartParam(request, myDriver)); getDefaultMultiPartParam(request, myDriver));
Assertions.assertEquals(jdbcDriverPluginService.getJdbcDriverClass(DEFAULT_ORGANIZATION_ID), Arrays.asList("io.jianxing.MyDriver", "com.mysql.cj.jdbc.Driver")); Assertions.assertEquals(jdbcDriverPluginService.getJdbcDriverClass(DEFAULT_ORGANIZATION_ID), Arrays.asList("io.jianxing.MyDriver", "com.mysql.cj.jdbc.Driver"));
// 校验QUOTA动上传成功
request.setName("cloud-quota-plugin");
request.setOrganizationIds(Arrays.asList(org.getId()));
File quota = new File(
this.getClass().getClassLoader().getResource("file/cloud-quota-plugin-3.x.jar")
.getPath()
);
this.requestMultipartWithOkAndReturn(DEFAULT_ADD,
getDefaultMultiPartParam(request, quota));
// 清理掉
this.requestGetWithOk(DEFAULT_DELETE, "cloud-quota-plugin");
// @@重名校验异常 // @@重名校验异常
// 校验插件名称重名 // 校验插件名称重名
assertErrorCode(this.requestMultipart(DEFAULT_ADD, assertErrorCode(this.requestMultipart(DEFAULT_ADD,