- Enhance rule checking in rule managers and Sentinel Dashboard frontend - Enhance error information when reporting invalid fields in rule dialog Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
4198d217e5
commit
0c15dd9fe3
|
|
@ -151,6 +151,7 @@ public final class AuthorityRuleManager {
|
|||
}
|
||||
|
||||
static boolean isValidRule(AuthorityRule rule) {
|
||||
return rule != null && !StringUtil.isBlank(rule.getResource());
|
||||
return rule != null && !StringUtil.isBlank(rule.getResource())
|
||||
&& rule.getStrategy() >= 0 && StringUtil.isNotBlank(rule.getLimitApp());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,12 @@ public class DegradeRule extends AbstractRule {
|
|||
private static ScheduledExecutorService pool = Executors.newScheduledThreadPool(
|
||||
Runtime.getRuntime().availableProcessors(), new NamedThreadFactory("sentinel-degrade-reset-task", true));
|
||||
|
||||
public DegradeRule() {}
|
||||
|
||||
public DegradeRule(String resourceName) {
|
||||
setResource(resourceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* RT threshold or exception ratio threshold count.
|
||||
*/
|
||||
|
|
@ -80,8 +86,9 @@ public class DegradeRule extends AbstractRule {
|
|||
return grade;
|
||||
}
|
||||
|
||||
public void setGrade(int grade) {
|
||||
public DegradeRule setGrade(int grade) {
|
||||
this.grade = grade;
|
||||
return this;
|
||||
}
|
||||
|
||||
private AtomicLong passCount = new AtomicLong(0);
|
||||
|
|
@ -92,8 +99,9 @@ public class DegradeRule extends AbstractRule {
|
|||
return count;
|
||||
}
|
||||
|
||||
public void setCount(double count) {
|
||||
public DegradeRule setCount(double count) {
|
||||
this.count = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isCut() {
|
||||
|
|
@ -112,8 +120,9 @@ public class DegradeRule extends AbstractRule {
|
|||
return timeWindow;
|
||||
}
|
||||
|
||||
public void setTimeWindow(int timeWindow) {
|
||||
public DegradeRule setTimeWindow(int timeWindow) {
|
||||
this.timeWindow = timeWindow;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -167,7 +167,16 @@ public class DegradeRuleManager {
|
|||
|
||||
}
|
||||
|
||||
private static boolean isValidRule(DegradeRule rule) {
|
||||
return rule != null && !StringUtil.isBlank(rule.getResource()) && rule.getCount() >= 0;
|
||||
public static boolean isValidRule(DegradeRule rule) {
|
||||
boolean baseValid = rule != null && !StringUtil.isBlank(rule.getResource())
|
||||
&& rule.getCount() >= 0 && rule.getTimeWindow() > 0;
|
||||
if (!baseValid) {
|
||||
return false;
|
||||
}
|
||||
// Check exception ratio mode.
|
||||
if (rule.getGrade() == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO && rule.getCount() > 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,31 @@ public class FlowRuleManager {
|
|||
|
||||
}
|
||||
|
||||
private static boolean isValidRule(FlowRule rule) {
|
||||
return rule != null && !StringUtil.isBlank(rule.getResource());
|
||||
public static boolean isValidRule(FlowRule rule) {
|
||||
boolean baseValid = rule != null && !StringUtil.isBlank(rule.getResource()) && rule.getCount() >= 0
|
||||
&& rule.getGrade() >= 0 && rule.getStrategy() >= 0 && rule.getControlBehavior() >= 0;
|
||||
if (!baseValid) {
|
||||
return false;
|
||||
}
|
||||
// Check strategy and control (shaping) behavior.
|
||||
return checkStrategyField(rule) && checkControlBehaviorField(rule);
|
||||
}
|
||||
|
||||
private static boolean checkStrategyField(/*@NonNull*/ FlowRule rule) {
|
||||
if (rule.getStrategy() == RuleConstant.STRATEGY_RELATE || rule.getStrategy() == RuleConstant.STRATEGY_CHAIN) {
|
||||
return StringUtil.isNotBlank(rule.getRefResource());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean checkControlBehaviorField(/*@NonNull*/ FlowRule rule) {
|
||||
switch (rule.getControlBehavior()) {
|
||||
case RuleConstant.CONTROL_BEHAVIOR_WARM_UP:
|
||||
return rule.getWarmUpPeriodSec() > 0;
|
||||
case RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER:
|
||||
return rule.getMaxQueueingTimeMs() > 0;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,13 @@ public class AuthorityRuleManagerTest {
|
|||
AuthorityRule ruleB = null;
|
||||
AuthorityRule ruleC = new AuthorityRule();
|
||||
ruleC.setResource("abc");
|
||||
AuthorityRule ruleD = new AuthorityRule();
|
||||
ruleD.setResource("bcd").setLimitApp("abc");
|
||||
|
||||
assertFalse(AuthorityRuleManager.isValidRule(ruleA));
|
||||
assertFalse(AuthorityRuleManager.isValidRule(ruleB));
|
||||
assertTrue(AuthorityRuleManager.isValidRule(ruleC));
|
||||
assertFalse(AuthorityRuleManager.isValidRule(ruleC));
|
||||
assertTrue(AuthorityRuleManager.isValidRule(ruleD));
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.degrade;
|
||||
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test cases for {@link DegradeRuleManager}.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class DegradeRuleManagerTest {
|
||||
|
||||
@Test
|
||||
public void testIsValidRule() {
|
||||
DegradeRule rule1 = new DegradeRule("abc");
|
||||
DegradeRule rule2 = new DegradeRule("cde")
|
||||
.setCount(100)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||
.setTimeWindow(-1);
|
||||
DegradeRule rule3 = new DegradeRule("xx")
|
||||
.setCount(1.1)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
|
||||
.setTimeWindow(2);
|
||||
DegradeRule rule4 = new DegradeRule("yy")
|
||||
.setCount(-3)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)
|
||||
.setTimeWindow(2);
|
||||
assertFalse(DegradeRuleManager.isValidRule(rule1));
|
||||
assertFalse(DegradeRuleManager.isValidRule(rule2));
|
||||
assertFalse(DegradeRuleManager.isValidRule(rule3));
|
||||
assertTrue(DegradeRuleManager.isValidRule(rule3.setCount(1.0d)));
|
||||
assertTrue(DegradeRuleManager.isValidRule(rule3.setCount(0.0d)));
|
||||
assertFalse(DegradeRuleManager.isValidRule(rule4));
|
||||
}
|
||||
}
|
||||
|
|
@ -81,13 +81,41 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
|
|||
});
|
||||
};
|
||||
|
||||
function checkRuleValid(rule) {
|
||||
if (rule.resource === undefined || rule.resource === '') {
|
||||
alert('资源名称不能为空');
|
||||
return false;
|
||||
}
|
||||
if (rule.grade === undefined || rule.grade < 0) {
|
||||
alert('未知的降级类型');
|
||||
return false;
|
||||
}
|
||||
if (rule.count === undefined || rule.count === '' || rule.count < 0) {
|
||||
alert('降级阈值不能为空或小于 0');
|
||||
return false;
|
||||
}
|
||||
if (rule.timeWindow === undefined || rule.timeWindow === '' || rule.timeWindow <= 0) {
|
||||
alert('降级时间窗口必须大于 0');
|
||||
return false;
|
||||
}
|
||||
// 异常比率类型.
|
||||
if (rule.grade == 1 && rule.count > 1) {
|
||||
alert('异常比率超出范围:[0.0 - 1.0]');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
$scope.saveRule = function () {
|
||||
if ($scope.degradeRuleDialog.type == 'add') {
|
||||
if (!checkRuleValid($scope.currentRule)) {
|
||||
return;
|
||||
}
|
||||
if ($scope.degradeRuleDialog.type === 'add') {
|
||||
addNewRule($scope.currentRule);
|
||||
} else if ($scope.degradeRuleDialog.type == 'edit') {
|
||||
} else if ($scope.degradeRuleDialog.type === 'edit') {
|
||||
saveRule($scope.currentRule, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var confirmDialog;
|
||||
$scope.deleteRule = function (rule) {
|
||||
|
|
|
|||
|
|
@ -88,13 +88,58 @@ app.controller('FlowCtl', ['$scope', '$stateParams', 'FlowService', 'ngDialog',
|
|||
});
|
||||
};
|
||||
|
||||
function notNumberAtLeastZero(num) {
|
||||
return num === undefined || num === '' || isNaN(num) || num < 0;
|
||||
}
|
||||
|
||||
function notNumberGreaterThanZero(num) {
|
||||
return num === undefined || num === '' || isNaN(num) || num <= 0;
|
||||
}
|
||||
|
||||
function checkRuleValid(rule) {
|
||||
if (rule.resource === undefined || rule.resource === '') {
|
||||
alert('资源名称不能为空');
|
||||
return false;
|
||||
}
|
||||
if (rule.count === undefined || rule.count < 0) {
|
||||
alert('限流阈值必须大于等于 0');
|
||||
return false;
|
||||
}
|
||||
if (rule.strategy === undefined || rule.strategy < 0) {
|
||||
alert('无效的流控模式');
|
||||
return false;
|
||||
}
|
||||
if (rule.strategy == 1 || rule.strategy == 2) {
|
||||
if (rule.refResource === undefined || rule.refResource === '') {
|
||||
alert('请填写关联资源或入口');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (rule.controlBehavior === undefined || rule.controlBehavior < 0) {
|
||||
alert('无效的流控整形方式');
|
||||
return false;
|
||||
}
|
||||
if (rule.controlBehavior == 1 && notNumberGreaterThanZero(rule.warmUpPeriodSec)) {
|
||||
alert('预热时长必须大于 0');
|
||||
return false;
|
||||
}
|
||||
if (rule.controlBehavior == 2 && notNumberGreaterThanZero(rule.maxQueueingTimeMs)) {
|
||||
alert('排队超时时间必须大于 0');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
$scope.saveRule = function () {
|
||||
if ($scope.flowRuleDialog.type == 'add') {
|
||||
if (!checkRuleValid($scope.currentRule)) {
|
||||
return;
|
||||
}
|
||||
if ($scope.flowRuleDialog.type === 'add') {
|
||||
addNewRule($scope.currentRule);
|
||||
} else if ($scope.flowRuleDialog.type == 'edit') {
|
||||
} else if ($scope.flowRuleDialog.type === 'edit') {
|
||||
saveRule($scope.currentRule, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var confirmDialog;
|
||||
$scope.deleteRule = function (rule) {
|
||||
|
|
@ -115,7 +160,7 @@ app.controller('FlowCtl', ['$scope', '$stateParams', 'FlowService', 'ngDialog',
|
|||
};
|
||||
|
||||
$scope.confirm = function () {
|
||||
if ($scope.confirmDialog.type == 'delete_rule') {
|
||||
if ($scope.confirmDialog.type === 'delete_rule') {
|
||||
deleteRule($scope.currentRule);
|
||||
} else {
|
||||
console.error('error');
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
</div>
|
||||
<label class="col-sm-2 control-label">时间窗口</label>
|
||||
<div class="col-sm-4">
|
||||
<input type='number' class="form-control highlight-border" ng-model='currentRule.timeWindow' placeholder="降级时间间隔, 单位秒" />
|
||||
<input type='number' min="0" class="form-control highlight-border" ng-model='currentRule.timeWindow' placeholder="降级时间间隔, 单位秒" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">流控应用</label>
|
||||
<label class="col-sm-2 control-label" title="流控针对应用,即流量入口的调用来源(origin)">流控应用</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control highlight-border" ng-model='currentRule.limitApp' placeholder='指调用方,"default"表示所有应用。'
|
||||
/>
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
</div>
|
||||
<label class="col-sm-2 control-label">单机阈值</label>
|
||||
<div class="col-sm-3">
|
||||
<input type='number' class="form-control highlight-border" ng-model='currentRule.count' placeholder="单机阈值" />
|
||||
<input type='number' min="0" class="form-control highlight-border" ng-model='currentRule.count' placeholder="单机阈值" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue