sentinel1.8.3持久化教程,使用Nacos作为数据源
说明!!!
由于原文存在一定的问题
1、熔断有问题,无法添加修改删除。
2、流控的修改有问题,修改无法进行保存。
所以本人进行了一定的修改。最后感谢大佬的启发。
如果配置过程中依旧出现问题,可以直接使用我做好的Jar包,下载地址:
https://download.csdn.net/download/c_2333/86733449
如果遇到项目打包或者安装的时候出现问题,首先检查自己的Jar包、依赖、插件是否导入,其次,Maven版本需要在3.8以上,否则也会打包失败,需要注意的是Idea版本2020(或者其他旧版本)与Maven最新版(3.8)以上可能(注意是可能!!!)会发生一些未知Bug,建议打包完成后更改回原来的版本。
前言
一:sentinel持久化到nacos(全部配置)
二:sentinel控制台的改造(全部代码)
实现原理:
a) 控制台推送规则到Nacos/远程配置中心
b) Sentinel client 监听Nacos配置变化,更新本地缓存
配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel
代码
配置文件
在客户端中配置以下内容
#流量控制
# nacos的访问地址,我这里是nigix代理nacos的集群地址
spring.cloud.sentinel.datasource.flow.nacos.server-addr=127.0.0.1:8848
#与sentinel控制台的namespeace统一
spring.cloud.sentinel.datasource.flow.nacos.namespace=
#nacos中存储规则的dataId,对于dataId使用了${spring.application.name}变量,这样可以根据应用名来区分不同的规则配置
spring.cloud.sentinel.datasource.flow.nacos.data-id=${spring.application.name}-flow-rules
#nacos中存储规则的groupId
spring.cloud.sentinel.datasource.flow.nacos.group-id=SENTINEL_GROUP
#定义存储的规则类型
# 规则类型,取值见:
# org.springframework.cloud.alibaba.sentinel.datasource.RuleType
spring.cloud.sentinel.datasource.flow.nacos.rule-type=flow
#除流控以外的其他规则配置,可以选择性配置,也就是持久化哪个规则就配哪个
#熔断降级
spring.cloud.sentinel.datasource.degrade.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.degrade.nacos.namespace=
spring.cloud.sentinel.datasource.degrade.nacos.data-id=${spring.application.name}-degrade-rules
spring.cloud.sentinel.datasource.degrade.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.degrade.nacos.rule-type=degrade
#系统规则
spring.cloud.sentinel.datasource.system.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.system.nacos.namespace=
spring.cloud.sentinel.datasource.system.nacos.data-id=${spring.application.name}-system-rules
spring.cloud.sentinel.datasource.system.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.system.nacos.rule-type=system
#授权规则
spring.cloud.sentinel.datasource.authority.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.authority.nacos.namespace=
spring.cloud.sentinel.datasource.authority.nacos.data-id=${spring.application.name}-authority-rules
spring.cloud.sentinel.datasource.authority.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.authority.nacos.rule-type=authority
#热点规则
spring.cloud.sentinel.datasource.param-flow.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.param-flow.nacos.namespace=
spring.cloud.sentinel.datasource.param-flow.nacos.data-id=${spring.application.name}-param-flow-rules
spring.cloud.sentinel.datasource.param-flow.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.param-flow.nacos.rule-type=param_flow
改造sentinel控制台:
由于sentinel都将规则内容存入内存中,在重启服务或者5分钟之后,规则将被清除,所有这里修改sentinel控制台,使规则在nacos中实现增删改的储存,实现持久化。
sentinel控制台application.properties中加入:
application.properties中增加配置
server.port=8080
#nacos的集群地址
nacos.address=127.0.0.1:8848
#二选一public为空,namespeace为uuid,这里与dubbo服务一致
nacos.namespace=
#nacos.namespace=16b7fa67-d3e0-47e4-bc0d-76056712afc4
增加指定类 *在rule文件夹下增加nacos文件夹,在nacos文件夹下创建5个规则存储和拉取所需要的class,在nacos文件夹下增加NacosConfig和NacosConfigUtil配置类,在util中增加JSONUtils工具类。
增加类中具体的代码如下:
JSONUtils
public class JSONUtils {
public static <T> String toJSONString(Object object) {
try {
return new ObjectMapper().writeValueAsString(object);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}
public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return new ObjectMapper()
.getTypeFactory()
.constructParametricType(collectionClass, elementClasses);
}
public static <T> List<T> parseObject(Class<T> clazz, String string) {
JavaType javaType = getCollectionType(ArrayList.class, clazz);
try {
return (List<T>) new ObjectMapper().readValue(string, javaType);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
}
NacosConfig
@Configuration
public class NacosConfig {
@Value("${nacos.address}")
private String address;
@Value("${nacos.namespace}")
private String namespace;
@Bean
public ConfigService nacosConfigService() throws Exception {
Properties properties = new Properties();
//nacos集群地址
properties.put(PropertyKeyConst.SERVER_ADDR,address);
//namespace为空即为public
properties.put(PropertyKeyConst.NAMESPACE,namespace);
return ConfigFactory.createConfigService(properties);
}
}
NacosConfigUtil
public final class NacosConfigUtil {
public static final String GROUP_ID = "SENTINEL_GROUP";
public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
public static final String DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";
public static final String SYSTEM_DATA_ID_POSTFIX = "-system-rules";
public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-flow-rules";
public static final String AUTHORITY_DATA_ID_POSTFIX = "-authority-rules";
public static final String DASHBOARD_POSTFIX = "-sentinel-dashboard";
public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";
/**
* cc for `cluster-client`
*/
public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";
/**
* cs for `cluster-server`
*/
public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";
public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";
public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";
private NacosConfigUtil() {}
/**
*
* 将规则序列化成JSON文本,存储到Nacos server中
*
* @param configService nacos config service
* @param app 应用名称
* @param postfix 规则后缀 eg.NacosConfigUtil.FLOW_DATA_ID_POSTFIX
* @param rules 规则对象
* @throws NacosException 异常
*/
public static <T> void setRuleStringToNacos(ConfigService configService, String app, String postfix, List<T> rules) throws NacosException {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
List<Rule> ruleForApp = rules.stream()
.map(rule -> {
RuleEntity rule1 = (RuleEntity) rule;
System.out.println(rule1.getClass());
Rule rule2 = rule1.toRule();
System.out.println(rule2.getClass());
return rule2;
})
.collect(Collectors.toList());
String dataId = genDataId(app, postfix);
/**
* 俩种存储只是入参不同,为了满足功能的实现,存入nacos后,会有俩个配置,以后继续完善
*/
// 存储,控制微服务使用,即可以起到拦截作用,但是由于无法显示到控制台
configService.publishConfig(
dataId,
NacosConfigUtil.GROUP_ID,
JSONUtils.toJSONString(ruleForApp)
);
// 存储,给控制台显示使用,由于数据太多,会出现转化异常,虽然可以提供控制台显示,但是无法对微服务进行保护
configService.publishConfig(
dataId + DASHBOARD_POSTFIX,
NacosConfigUtil.GROUP_ID,
JSONUtils.toJSONString(rules)
);
}
/**
*
* 从Nacos server中查询响应规则,并将其反序列化成对应Rule实体
*
* @param configService nacos config service
* @param appName 应用名称
* @param postfix 规则后缀 eg.NacosConfigUtil.FLOW_DATA_ID_POSTFIX
* @param clazz 类
* @param <T> 泛型
* @return 规则对象列表
* @throws NacosException 异常
*/
public static <T> List<T> getRuleEntitiesFromNacos(ConfigService configService, String appName, String postfix, Class<T> clazz) throws NacosException {
String rules = configService.getConfig(
genDataId(appName, postfix) + DASHBOARD_POSTFIX,
NacosConfigUtil.GROUP_ID,
3000
);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return JSONUtils.parseObject(clazz, rules);
}
private static String genDataId(String appName, String postfix) {
return appName + postfix;
}
}
AuthorityRuleNacosProvider
@Component("authorityRuleNacosProvider")
public class AuthorityRuleNacosProvider implements DynamicRuleProvider<List<AuthorityRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public List<AuthorityRuleEntity> getRules(String appName) throws Exception {
return NacosConfigUtil.getRuleEntitiesFromNacos(
this.configService,
appName,
NacosConfigUtil.AUTHORITY_DATA_ID_POSTFIX,
AuthorityRuleEntity.class
);
}
}
AuthorityRuleNacosPublisher
@Component("authorityRuleNacosPublisher")
public class AuthorityRuleNacosPublisher implements DynamicRulePublisher<List<AuthorityRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public void publish(String app, List<AuthorityRuleEntity> rules) throws Exception {
NacosConfigUtil.setRuleStringToNacos(
this.configService,
app,
NacosConfigUtil.AUTHORITY_DATA_ID_POSTFIX,
rules
);
}
}
DegradeRuleNacosProvider
@Component("degradeRuleNacosProvider")
public class DegradeRuleNacosProvider implements DynamicRuleProvider<List<DegradeRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public List<DegradeRuleEntity> getRules(String appName) throws Exception {
return NacosConfigUtil.getRuleEntitiesFromNacos(
this.configService,
appName,
NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
DegradeRuleEntity.class
);
}
}
DegradeRuleNacosPublisher
@Component("degradeRuleNacosPublisher")
public class DegradeRuleNacosPublisher implements DynamicRulePublisher<List<DegradeRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public void publish(String app, List<DegradeRuleEntity> rules) throws Exception {
NacosConfigUtil.setRuleStringToNacos(
this.configService,
app,
NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
rules
);
}
}
FlowRuleNacosProvider
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
return NacosConfigUtil.getRuleEntitiesFromNacos(
this.configService,
appName,
NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
FlowRuleEntity.class
);
}
}
FlowRuleNacosPublisher
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
NacosConfigUtil.setRuleStringToNacos(
this.configService,
app,
NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
rules
);
}
}
ParamFlowRuleNacosProvider
@Component("paramFlowRuleNacosProvider")
public class ParamFlowRuleNacosProvider implements DynamicRuleProvider<List<ParamFlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public List<ParamFlowRuleEntity> getRules(String appName) throws Exception {
return NacosConfigUtil.getRuleEntitiesFromNacos(
this.configService,
appName,
NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
ParamFlowRuleEntity.class
);
}
}
ParamFlowRuleNacosPublisher
@Component("paramFlowRuleNacosPublisher")
public class ParamFlowRuleNacosPublisher implements DynamicRulePublisher<List<ParamFlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public void publish(String app, List<ParamFlowRuleEntity> rules) throws Exception {
NacosConfigUtil.setRuleStringToNacos(
this.configService,
app,
NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
rules
);
}
}
SystemRuleNacosProvider
@Component("systemRuleNacosProvider")
public class SystemRuleNacosProvider implements DynamicRuleProvider<List<SystemRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public List<SystemRuleEntity> getRules(String appName) throws Exception {
return NacosConfigUtil.getRuleEntitiesFromNacos(
this.configService,
appName,
NacosConfigUtil.SYSTEM_DATA_ID_POSTFIX,
SystemRuleEntity.class
);
}
}
SystemRuleNacosPublisher
@Component("systemRuleNacosPublisher")
public class SystemRuleNacosPublisher implements DynamicRulePublisher<List<SystemRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public void publish(String app, List<SystemRuleEntity> rules) throws Exception {
NacosConfigUtil.setRuleStringToNacos(
this.configService,
app,
NacosConfigUtil.SYSTEM_DATA_ID_POSTFIX,
rules
);
}
}
* 修改5种规则crud的controller层 主要修改数据的存储,将原来存入内存的规则,现在存入nacos,并将nacos的数据push到sentinel的数据源中。
AuthorityRuleController
@RestController
@RequestMapping(value = "/authority")
public class AuthorityRuleController {
private final Logger logger = LoggerFactory.getLogger(AuthorityRuleController.class);
@Autowired
@Qualifier("authorityRuleNacosProvider")
private DynamicRuleProvider<List<AuthorityRuleEntity>> ruleProvider;
@Autowired
@Qualifier("authorityRuleNacosPublisher")
private DynamicRulePublisher<List<AuthorityRuleEntity>> rulePublisher;
/* @Autowired
private SentinelApiClient sentinelApiClient;*/
@Autowired
private RuleRepository<AuthorityRuleEntity, Long> repository;
@GetMapping("/rules")
@AuthAction(PrivilegeType.READ_RULE)
public Result<List<AuthorityRuleEntity>> apiQueryAllRulesForMachine(@RequestParam String app,
@RequestParam String ip,
@RequestParam Integer port) {
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app cannot be null or empty");
}
if (StringUtil.isEmpty(ip)) {
return Result.ofFail(-1, "ip cannot be null or empty");
}
if (port == null || port <= 0) {
return Result.ofFail(-1, "Invalid parameter: port");
}
try {
// List<AuthorityRuleEntity> rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);
List<AuthorityRuleEntity> rules = ruleProvider.getRules(app);
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (Throwable throwable) {
logger.error("Error when querying authority rules", throwable);
return Result.ofFail(-1, throwable.getMessage());
}
}
private <R> Result<R> checkEntityInternal(AuthorityRuleEntity entity) {
if (entity == null) {
return Result.ofFail(-1, "bad rule body");
}
if (StringUtil.isBlank(entity.getApp())) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isBlank(entity.getIp())) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (entity.getPort() == null || entity.getPort() <= 0) {
return Result.ofFail(-1, "port can't be null");
}
if (entity.getRule() == null) {
return Result.ofFail(-1, "rule can't be null");
}
if (StringUtil.isBlank(entity.getResource())) {
return Result.ofFail(-1, "resource name cannot be null or empty");
}
if (StringUtil.isBlank(entity.getLimitApp())) {
return Result.ofFail(-1, "limitApp should be valid");
}
if (entity.getStrategy() != RuleConstant.AUTHORITY_WHITE
&& entity.getStrategy() != RuleConstant.AUTHORITY_BLACK) {
return Result.ofFail(-1, "Unknown strategy (must be blacklist or whitelist)");
}
return null;
}
@PostMapping("/rule")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<AuthorityRuleEntity> apiAddAuthorityRule(@RequestBody AuthorityRuleEntity entity) {
Result<AuthorityRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
}
entity.setId(null);
Date date = new Date();
entity.setGmtCreate(date);
entity.setGmtModified(date);
try {
entity = repository.save(entity);
publishRules(entity.getApp());
} catch (Throwable throwable) {
logger.error("Failed to add flow rule", throwable);
return Result.ofThrowable(-1, throwable);
}
return Result.ofSuccess(entity);
}
@PutMapping("/rule/{id}")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<AuthorityRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,
@RequestBody AuthorityRuleEntity entity) {
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
Result<AuthorityRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
}
entity.setId(id);
Date date = new Date();
entity.setGmtCreate(null);
entity.setGmtModified(date);
try {
entity = repository.save(entity);
if (entity == null) {
return Result.ofFail(-1, "Failed to save authority rule");
}
publishRules(entity.getApp());
} catch (Throwable throwable) {
logger.error("Failed to save authority rule", throwable);
return Result.ofThrowable(-1, throwable);
}
return Result.ofSuccess(entity);
}
@DeleteMapping("/rule/{id}")
@AuthAction(PrivilegeType.DELETE_RULE)
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
AuthorityRuleEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofSuccess(null);
}
try {
repository.delete(id);
publishRules(oldEntity.getApp());
} catch (Exception e) {
return Result.ofFail(-1, e.getMessage());
}
return Result.ofSuccess(id);
}
/* private boolean publishRules(String app, String ip, Integer port) {
List<AuthorityRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setAuthorityRuleOfMachine(app, ip, port, rules);
}*/
private void publishRules(String app) throws Exception {
List<AuthorityRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
}
DegradeController(原文写的有问题,这里进行了修改)
@RestController
@RequestMapping(value = "/degrade")
public class DegradeController {
private final Logger logger = LoggerFactory.getLogger(DegradeController.class);
@Autowired
private InMemDegradeRuleStore repository;
@Autowired
@Qualifier("degradeRuleNacosProvider")
private DynamicRuleProvider<List<DegradeRuleEntity>> ruleProvider;
@Autowired
@Qualifier("degradeRuleNacosPublisher")
private DynamicRulePublisher<List<DegradeRuleEntity>> rulePublisher;
/*@Autowired
private SentinelApiClient sentinelApiClient;*/
@GetMapping("/rules.json")
@AuthAction(PrivilegeType.READ_RULE)
public Result<List<DegradeRuleEntity>> queryMachineRules(String app, String ip, Integer port) {
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isEmpty(ip)) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (port == null) {
return Result.ofFail(-1, "port can't be null");
}
try {
// List<DegradeRuleEntity> rules = sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port);
//去nacos中取数据
List<DegradeRuleEntity> rules = ruleProvider.getRules(app);
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (Throwable throwable) {
logger.error("queryApps error:", throwable);
return Result.ofThrowable(-1, throwable);
}
}
@PostMapping("/rule")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<DegradeRuleEntity> add(@RequestBody DegradeRuleEntity entity) {
if (StringUtil.isBlank(entity.getApp())) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isBlank(entity.getIp())) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (entity.getPort() == null) {
return Result.ofFail(-1, "port can't be null");
}
if (StringUtil.isBlank(entity.getLimitApp())) {
return Result.ofFail(-1, "limitApp can't be null or empty");
}
if (StringUtil.isBlank(entity.getResource())) {
return Result.ofFail(-1, "resource can't be null or empty");
}
if (entity.getCount() == null) {
return Result.ofFail(-1, "count can't be null");
}
if (entity.getTimeWindow() == null) {
return Result.ofFail(-1, "timeWindow can't be null");
}
if (entity.getGrade() == null) {
return Result.ofFail(-1, "grade can't be null");
}
if (entity.getGrade() < RuleConstant.DEGRADE_GRADE_RT || entity.getGrade() > RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {
return Result.ofFail(-1, "Invalid grade: " + entity.getGrade());
}
entity.setApp(entity.getApp().trim());
entity.setIp(entity.getIp().trim());
entity.setPort(entity.getPort());
entity.setLimitApp(entity.getLimitApp().trim());
entity.setResource(entity.getResource().trim());
entity.setCount(entity.getCount());
entity.setTimeWindow(entity.getTimeWindow());
entity.setGrade(entity.getGrade());
entity.setMinRequestAmount(entity.getMinRequestAmount());
entity.setSlowRatioThreshold(entity.getSlowRatioThreshold());
entity.setStatIntervalMs(entity.getStatIntervalMs());
Date date = new Date();
entity.setGmtCreate(date);
entity.setGmtModified(date);
try {
entity = repository.save(entity);
//推送信息
publishRules(entity.getApp());
} catch (Throwable throwable) {
logger.error("add error:", throwable);
return Result.ofThrowable(-1, throwable);
}
/* if (!publishRules(app, ip, port)) {
logger.info("publish degrade rules fail after rule add");
}*/
return Result.ofSuccess(entity);
}
@PutMapping("/rule/{id}")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<DegradeRuleEntity> updateIfNotNull(@PathVariable("id") Long id,
@RequestBody DegradeRuleEntity entity) {
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
if (entity.getGrade() != null) {
if (entity.getGrade() < RuleConstant.DEGRADE_GRADE_RT || entity.getGrade() > RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {
return Result.ofFail(-1, "Invalid grade: " + entity.getGrade() );
}
}
DegradeRuleEntity entity2 = repository.findById(id);
if (entity2 == null) {
return Result.ofFail(-1, "id " + id + " dose not exist");
}
if (StringUtil.isNotBlank(entity.getApp())) {
entity2.setApp(entity.getApp().trim());
}
if (StringUtil.isNotBlank(entity.getLimitApp())) {
entity2.setLimitApp(entity.getLimitApp().trim());
}
if (StringUtil.isNotBlank(entity.getResource())) {
entity2.setResource(entity.getResource().trim());
}
if (entity.getCount() != null) {
entity2.setCount(entity.getCount());
}
if (entity.getTimeWindow() != null) {
entity2.setTimeWindow(entity.getTimeWindow());
}
if (entity.getGrade() != null) {
entity2.setGrade(entity.getGrade());
}
if(entity.getMinRequestAmount()!=null){
entity2.setMinRequestAmount(entity.getMinRequestAmount());
}
if(entity.getStatIntervalMs()!=null){
entity2.setStatIntervalMs(entity.getStatIntervalMs());
}
if(entity.getSlowRatioThreshold()!=null){
entity2.setSlowRatioThreshold(entity.getSlowRatioThreshold());
}
Date date = new Date();
entity2.setGmtModified(date);
try {
entity2 = repository.save(entity2);
//推送规则
publishRules(entity2.getApp());
} catch (Throwable throwable) {
logger.error("save error:", throwable);
return Result.ofThrowable(-1, throwable);
}
/* if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {
logger.info("publish degrade rules fail after rule update");
}*/
return Result.ofSuccess(entity2);
}
@DeleteMapping("/rule/{id}")
@AuthAction(PrivilegeType.DELETE_RULE)
public Result<Long> delete(@PathVariable("id") Long id) {
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
DegradeRuleEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofSuccess(null);
}
try {
repository.delete(id);
//推送规则
publishRules(oldEntity.getApp());
} catch (Throwable throwable) {
logger.error("delete error:", throwable);
return Result.ofThrowable(-1, throwable);
}
/* if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {
logger.info("publish degrade rules fail after rule delete");
}*/
return Result.ofSuccess(id);
}
/* private boolean publishRules(String app, String ip, Integer port) {
List<DegradeRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setDegradeRuleOfMachine(app, ip, port, rules);
}*/
private void publishRules(String app) throws Exception {
List<DegradeRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
}
FlowControllerV1
@RestController
@RequestMapping(value = "/v1/flow")
public class FlowControllerV1 {
private final Logger logger = LoggerFactory.getLogger(FlowControllerV1.class);
@Autowired
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
/* @Autowired
private SentinelApiClient sentinelApiClient;*/
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
@GetMapping("/rules")
@AuthAction(PrivilegeType.READ_RULE)
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app) {
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
/* if (StringUtil.isEmpty(ip)) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (port == null) {
return Result.ofFail(-1, "port can't be null");
}*/
try {
// List<FlowRuleEntity> rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);
List<FlowRuleEntity> rules = ruleProvider.getRules(app);
if (rules != null && !rules.isEmpty()) {
for (FlowRuleEntity entity : rules) {
entity.setApp(app);
if (entity.getClusterConfig() != null && entity.getClusterConfig().getFlowId() != null) {
entity.setId(entity.getClusterConfig().getFlowId());
}
}
}
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (Throwable throwable) {
logger.error("Error when querying flow rules", throwable);
return Result.ofThrowable(-1, throwable);
}
}
private <R> Result<R> checkEntityInternal(FlowRuleEntity entity) {
if (entity == null) {
return Result.ofFail(-1, "invalid body");
}
if (StringUtil.isBlank(entity.getApp())) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isBlank(entity.getIp())) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (entity.getPort() == null) {
return Result.ofFail(-1, "port can't be null");
}
if (StringUtil.isBlank(entity.getLimitApp())) {
return Result.ofFail(-1, "limitApp can't be null or empty");
}
if (StringUtil.isBlank(entity.getResource())) {
return Result.ofFail(-1, "resource can't be null or empty");
}
if (entity.getGrade() == null) {
return Result.ofFail(-1, "grade can't be null");
}
if (entity.getGrade() != 0 && entity.getGrade() != 1) {
return Result.ofFail(-1, "grade must be 0 or 1, but " + entity.getGrade() + " got");
}
if (entity.getCount() == null || entity.getCount() < 0) {
return Result.ofFail(-1, "count should be at lease zero");
}
if (entity.getStrategy() == null) {
return Result.ofFail(-1, "strategy can't be null");
}
if (entity.getStrategy() != 0 && StringUtil.isBlank(entity.getRefResource())) {
return Result.ofFail(-1, "refResource can't be null or empty when strategy!=0");
}
if (entity.getControlBehavior() == null) {
return Result.ofFail(-1, "controlBehavior can't be null");
}
int controlBehavior = entity.getControlBehavior();
if (controlBehavior == 1 && entity.getWarmUpPeriodSec() == null) {
return Result.ofFail(-1, "warmUpPeriodSec can't be null when controlBehavior==1");
}
if (controlBehavior == 2 && entity.getMaxQueueingTimeMs() == null) {
return Result.ofFail(-1, "maxQueueingTimeMs can't be null when controlBehavior==2");
}
if (entity.isClusterMode() && entity.getClusterConfig() == null) {
return Result.ofFail(-1, "cluster config should be valid");
}
return null;
}
@PostMapping("/rule")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<FlowRuleEntity> apiAddFlowRule(@RequestBody FlowRuleEntity entity) {
Result<FlowRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
}
entity.setId(null);
Date date = new Date();
entity.setGmtCreate(date);
entity.setGmtModified(date);
entity.setLimitApp(entity.getLimitApp().trim());
entity.setResource(entity.getResource().trim());
try {
entity = repository.save(entity);
publishRules(entity.getApp());
} catch (Throwable throwable) {
logger.error("Failed to add flow rule", throwable);
return Result.ofThrowable(-1, throwable);
}
return Result.ofSuccess(entity);
}
@PutMapping("/save.json")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<FlowRuleEntity> apiUpdateFlowRule(Long id, String app,
String limitApp, String resource, Integer grade,
Double count, Integer strategy, String refResource,
Integer controlBehavior, Integer warmUpPeriodSec,
Integer maxQueueingTimeMs) {
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
FlowRuleEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofFail(-1, "id " + id + " does not exist");
}
//FlowRuleEntity entity = new FlowRuleEntity();
if(app!=null&&!app.isEmpty()){
oldEntity.setApp(app);
}
if(limitApp!=null&&!limitApp.isEmpty()){
oldEntity.setLimitApp(limitApp);
}
if(resource!=null&&!resource.isEmpty()){
oldEntity.setResource(resource);
}
if(grade!=null){
oldEntity.setGrade(grade);
}
if(count!=null){
oldEntity.setCount(count);
}
if(strategy!=null){
oldEntity.setStrategy(strategy);
}
if(refResource!=null&&!refResource.isEmpty()){
oldEntity.setRefResource(refResource);
}
if(controlBehavior!=null){
oldEntity.setControlBehavior(controlBehavior);
}
if(warmUpPeriodSec!=null){
oldEntity.setWarmUpPeriodSec(warmUpPeriodSec);
}
if(maxQueueingTimeMs!=null){
oldEntity.setMaxQueueingTimeMs(maxQueueingTimeMs);
}
Result<FlowRuleEntity> checkResult = checkEntityInternal(oldEntity);
if (checkResult != null) {
return checkResult;
}
Date date = new Date();
oldEntity.setGmtCreate(oldEntity.getGmtCreate());
oldEntity.setGmtModified(date);
try {
oldEntity = repository.save(oldEntity);
if (oldEntity == null) {
return Result.ofFail(-1, "save entity fail");
}
publishRules(oldEntity.getApp());
} catch (Throwable throwable) {
logger.error("Failed to update flow rule", throwable);
return Result.ofThrowable(-1, throwable);
}
return Result.ofSuccess(oldEntity);
}
@DeleteMapping("/delete.json")
@AuthAction(PrivilegeType.DELETE_RULE)
public Result<Long> apiDeleteFlowRule(Long id) {
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
FlowRuleEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofSuccess(null);
}
try {
repository.delete(id);
publishRules(oldEntity.getApp());
} catch (Exception e) {
return Result.ofFail(-1, e.getMessage());
}
return Result.ofSuccess(id);
}
/* private CompletableFuture<Void> publishRules(String app, String ip, Integer port) {
List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules);
}*/
private void publishRules(/*@NonNull*/ String app) throws Exception {
List<FlowRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
}
ParamFlowRuleController
@RestController
@RequestMapping(value = "/paramFlow")
public class ParamFlowRuleController {
private final Logger logger = LoggerFactory.getLogger(ParamFlowRuleController.class);
/* @Autowired
private SentinelApiClient sentinelApiClient;*/
@Autowired
@Qualifier("paramFlowRuleNacosProvider")
private DynamicRuleProvider<List<ParamFlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("paramFlowRuleNacosPublisher")
private DynamicRulePublisher<List<ParamFlowRuleEntity>> rulePublisher;
@Autowired
private AppManagement appManagement;
@Autowired
private RuleRepository<ParamFlowRuleEntity, Long> repository;
private boolean checkIfSupported(String app, String ip, int port) {
try {
return Optional.ofNullable(appManagement.getDetailApp(app))
.flatMap(e -> e.getMachine(ip, port))
.flatMap(m -> VersionUtils.parseVersion(m.getVersion())
.map(v -> v.greaterOrEqual(version020)))
.orElse(true);
// If error occurred or cannot retrieve machine info, return true.
} catch (Exception ex) {
return true;
}
}
@GetMapping("/rules")
@AuthAction(PrivilegeType.READ_RULE)
public Result<List<ParamFlowRuleEntity>> apiQueryAllRulesForMachine(@RequestParam String app,
@RequestParam String ip,
@RequestParam Integer port) {
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app cannot be null or empty");
}
if (StringUtil.isEmpty(ip)) {
return Result.ofFail(-1, "ip cannot be null or empty");
}
if (port == null || port <= 0) {
return Result.ofFail(-1, "Invalid parameter: port");
}
if (!checkIfSupported(app, ip, port)) {
return unsupportedVersion();
}
try {
/* return sentinelApiClient.fetchParamFlowRulesOfMachine(app, ip, port)
.thenApply(repository::saveAll)
.thenApply(Result::ofSuccess)
.get();*/
List<ParamFlowRuleEntity> rules = ruleProvider.getRules(app);
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (ExecutionException ex) {
logger.error("Error when querying parameter flow rules", ex.getCause());
if (isNotSupported(ex.getCause())) {
return unsupportedVersion();
} else {
return Result.ofThrowable(-1, ex.getCause());
}
} catch (Throwable throwable) {
logger.error("Error when querying parameter flow rules", throwable);
return Result.ofFail(-1, throwable.getMessage());
}
}
private boolean isNotSupported(Throwable ex) {
return ex instanceof CommandNotFoundException;
}
@PostMapping("/rule")
@AuthAction(AuthService.PrivilegeType.WRITE_RULE)
public Result<ParamFlowRuleEntity> apiAddParamFlowRule(@RequestBody ParamFlowRuleEntity entity) {
Result<ParamFlowRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
}
if (!checkIfSupported(entity.getApp(), entity.getIp(), entity.getPort())) {
return unsupportedVersion();
}
entity.setId(null);
entity.getRule().setResource(entity.getResource().trim());
Date date = new Date();
entity.setGmtCreate(date);
entity.setGmtModified(date);
try {
entity = repository.save(entity);
// publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get();
publishRules(entity.getApp());
return Result.ofSuccess(entity);
} catch (ExecutionException ex) {
logger.error("Error when adding new parameter flow rules", ex.getCause());
if (isNotSupported(ex.getCause())) {
return unsupportedVersion();
} else {
return Result.ofThrowable(-1, ex.getCause());
}
} catch (Throwable throwable) {
logger.error("Error when adding new parameter flow rules", throwable);
return Result.ofFail(-1, throwable.getMessage());
}
}
private <R> Result<R> checkEntityInternal(ParamFlowRuleEntity entity) {
if (entity == null) {
return Result.ofFail(-1, "bad rule body");
}
if (StringUtil.isBlank(entity.getApp())) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isBlank(entity.getIp())) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (entity.getPort() == null || entity.getPort() <= 0) {
return Result.ofFail(-1, "port can't be null");
}
if (entity.getRule() == null) {
return Result.ofFail(-1, "rule can't be null");
}
if (StringUtil.isBlank(entity.getResource())) {
return Result.ofFail(-1, "resource name cannot be null or empty");
}
if (entity.getCount() < 0) {
return Result.ofFail(-1, "count should be valid");
}
if (entity.getGrade() != RuleConstant.FLOW_GRADE_QPS) {
return Result.ofFail(-1, "Unknown mode (blockGrade) for parameter flow control");
}
if (entity.getParamIdx() == null || entity.getParamIdx() < 0) {
return Result.ofFail(-1, "paramIdx should be valid");
}
if (entity.getDurationInSec() <= 0) {
return Result.ofFail(-1, "durationInSec should be valid");
}
if (entity.getControlBehavior() < 0) {
return Result.ofFail(-1, "controlBehavior should be valid");
}
return null;
}
@PutMapping("/rule/{id}")
@AuthAction(AuthService.PrivilegeType.WRITE_RULE)
public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,
@RequestBody ParamFlowRuleEntity entity) {
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
ParamFlowRuleEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofFail(-1, "id " + id + " does not exist");
}
Result<ParamFlowRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
}
if (!checkIfSupported(entity.getApp(), entity.getIp(), entity.getPort())) {
return unsupportedVersion();
}
entity.setId(id);
Date date = new Date();
entity.setGmtCreate(oldEntity.getGmtCreate());
entity.setGmtModified(date);
try {
entity = repository.save(entity);
// publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get();
publishRules(entity.getApp());
return Result.ofSuccess(entity);
} catch (ExecutionException ex) {
logger.error("Error when updating parameter flow rules, id=" + id, ex.getCause());
if (isNotSupported(ex.getCause())) {
return unsupportedVersion();
} else {
return Result.ofThrowable(-1, ex.getCause());
}
} catch (Throwable throwable) {
logger.error("Error when updating parameter flow rules, id=" + id, throwable);
return Result.ofFail(-1, throwable.getMessage());
}
}
@DeleteMapping("/rule/{id}")
@AuthAction(PrivilegeType.DELETE_RULE)
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
if (id == null) {
return Result.ofFail(-1, "id cannot be null");
}
ParamFlowRuleEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofSuccess(null);
}
try {
repository.delete(id);
// publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort()).get();
publishRules(oldEntity.getApp());
return Result.ofSuccess(id);
} catch (ExecutionException ex) {
logger.error("Error when deleting parameter flow rules", ex.getCause());
if (isNotSupported(ex.getCause())) {
return unsupportedVersion();
} else {
return Result.ofThrowable(-1, ex.getCause());
}
} catch (Throwable throwable) {
logger.error("Error when deleting parameter flow rules", throwable);
return Result.ofFail(-1, throwable.getMessage());
}
}
/* private CompletableFuture<Void> publishRules(String app, String ip, Integer port) {
List<ParamFlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setParamFlowRuleOfMachine(app, ip, port, rules);
}*/
private void publishRules(String app) throws Exception {
List<ParamFlowRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
private <R> Result<R> unsupportedVersion() {
return Result.ofFail(4041,
"Sentinel client not supported for parameter flow control (unsupported version or dependency absent)");
}
private final SentinelVersion version020 = new SentinelVersion().setMinorVersion(2);
}
SystemController
@RestController
@RequestMapping("/system")
public class SystemController {
private final Logger logger = LoggerFactory.getLogger(SystemController.class);
@Autowired
private RuleRepository<SystemRuleEntity, Long> repository;
@Autowired
@Qualifier("systemRuleNacosProvider")
private DynamicRuleProvider<List<SystemRuleEntity>> ruleProvider;
@Autowired
@Qualifier("systemRuleNacosPublisher")
private DynamicRulePublisher<List<SystemRuleEntity>> rulePublisher;
/* @Autowired
private SentinelApiClient sentinelApiClient;*/
private <R> Result<R> checkBasicParams(String app, String ip, Integer port) {
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isEmpty(ip)) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (port == null) {
return Result.ofFail(-1, "port can't be null");
}
if (port <= 0 || port > 65535) {
return Result.ofFail(-1, "port should be in (0, 65535)");
}
return null;
}
@GetMapping("/rules.json")
@AuthAction(PrivilegeType.READ_RULE)
public Result<List<SystemRuleEntity>> apiQueryMachineRules(String app, String ip,
Integer port) {
Result<List<SystemRuleEntity>> checkResult = checkBasicParams(app, ip, port);
if (checkResult != null) {
return checkResult;
}
try {
// List<SystemRuleEntity> rules = sentinelApiClient.fetchSystemRuleOfMachine(app, ip, port);
List<SystemRuleEntity> rules = ruleProvider.getRules(app);
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (Throwable throwable) {
logger.error("Query machine system rules error", throwable);
return Result.ofThrowable(-1, throwable);
}
}
private int countNotNullAndNotNegative(Number... values) {
int notNullCount = 0;
for (int i = 0; i < values.length; i++) {
if (values[i] != null && values[i].doubleValue() >= 0) {
notNullCount++;
}
}
return notNullCount;
}
@RequestMapping("/new.json")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<SystemRuleEntity> apiAdd(String app, String ip, Integer port,
Double highestSystemLoad, Double highestCpuUsage, Long avgRt,
Long maxThread, Double qps) {
Result<SystemRuleEntity> checkResult = checkBasicParams(app, ip, port);
if (checkResult != null) {
return checkResult;
}
int notNullCount = countNotNullAndNotNegative(highestSystemLoad, avgRt, maxThread, qps, highestCpuUsage);
if (notNullCount != 1) {
return Result.ofFail(-1, "only one of [highestSystemLoad, avgRt, maxThread, qps,highestCpuUsage] "
+ "value must be set > 0, but " + notNullCount + " values get");
}
if (null != highestCpuUsage && highestCpuUsage > 1) {
return Result.ofFail(-1, "highestCpuUsage must between [0.0, 1.0]");
}
SystemRuleEntity entity = new SystemRuleEntity();
entity.setApp(app.trim());
entity.setIp(ip.trim());
entity.setPort(port);
// -1 is a fake value
if (null != highestSystemLoad) {
entity.setHighestSystemLoad(highestSystemLoad);
} else {
entity.setHighestSystemLoad(-1D);
}
if (null != highestCpuUsage) {
entity.setHighestCpuUsage(highestCpuUsage);
} else {
entity.setHighestCpuUsage(-1D);
}
if (avgRt != null) {
entity.setAvgRt(avgRt);
} else {
entity.setAvgRt(-1L);
}
if (maxThread != null) {
entity.setMaxThread(maxThread);
} else {
entity.setMaxThread(-1L);
}
if (qps != null) {
entity.setQps(qps);
} else {
entity.setQps(-1D);
}
Date date = new Date();
entity.setGmtCreate(date);
entity.setGmtModified(date);
try {
entity = repository.save(entity);
//推送
publishRules(app);
} catch (Throwable throwable) {
logger.error("Add SystemRule error", throwable);
return Result.ofThrowable(-1, throwable);
}
/* if (!publishRules(app, ip, port)) {
logger.warn("Publish system rules fail after rule add");
}*/
return Result.ofSuccess(entity);
}
@GetMapping("/save.json")
@AuthAction(PrivilegeType.WRITE_RULE)
public Result<SystemRuleEntity> apiUpdateIfNotNull(Long id, String app, Double highestSystemLoad,
Double highestCpuUsage, Long avgRt, Long maxThread, Double qps) {
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
SystemRuleEntity entity = repository.findById(id);
if (entity == null) {
return Result.ofFail(-1, "id " + id + " dose not exist");
}
if (StringUtil.isNotBlank(app)) {
entity.setApp(app.trim());
}
if (highestSystemLoad != null) {
if (highestSystemLoad < 0) {
return Result.ofFail(-1, "highestSystemLoad must >= 0");
}
entity.setHighestSystemLoad(highestSystemLoad);
}
if (highestCpuUsage != null) {
if (highestCpuUsage < 0) {
return Result.ofFail(-1, "highestCpuUsage must >= 0");
}
if (highestCpuUsage > 1) {
return Result.ofFail(-1, "highestCpuUsage must <= 1");
}
entity.setHighestCpuUsage(highestCpuUsage);
}
if (avgRt != null) {
if (avgRt < 0) {
return Result.ofFail(-1, "avgRt must >= 0");
}
entity.setAvgRt(avgRt);
}
if (maxThread != null) {
if (maxThread < 0) {
return Result.ofFail(-1, "maxThread must >= 0");
}
entity.setMaxThread(maxThread);
}
if (qps != null) {
if (qps < 0) {
return Result.ofFail(-1, "qps must >= 0");
}
entity.setQps(qps);
}
Date date = new Date();
entity.setGmtModified(date);
try {
entity = repository.save(entity);
//推送
publishRules(entity.getApp());
} catch (Throwable throwable) {
logger.error("save error:", throwable);
return Result.ofThrowable(-1, throwable);
}
/* if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {
logger.info("publish system rules fail after rule update");
}*/
return Result.ofSuccess(entity);
}
@RequestMapping("/delete.json")
@AuthAction(PrivilegeType.DELETE_RULE)
public Result<?> delete(Long id) {
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
SystemRuleEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofSuccess(null);
}
try {
repository.delete(id);
//推送
publishRules(oldEntity.getApp());
} catch (Throwable throwable) {
logger.error("delete error:", throwable);
return Result.ofThrowable(-1, throwable);
}
/* if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {
logger.info("publish system rules fail after rule delete");
}*/
return Result.ofSuccess(id);
}
/* private boolean publishRules(String app, String ip, Integer port) {
List<SystemRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setSystemRuleOfMachine(app, ip, port, rules);
}*/
private void publishRules(String app) throws Exception {
List<SystemRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
}
更多推荐
所有评论(0)