From faac56d306a9f33297b5d9a85cdcac33a3d384ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=80=85=E5=BC=88?=
Date: Mon, 7 Jan 2019 11:54:28 +0800
Subject: [PATCH 01/39] doc: add blog with Sentinel in action (#392)
---
doc/awesome-sentinel.md | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/doc/awesome-sentinel.md b/doc/awesome-sentinel.md
index d871eb2d43..c7112f21e0 100644
--- a/doc/awesome-sentinel.md
+++ b/doc/awesome-sentinel.md
@@ -33,4 +33,10 @@ You can also add to [sentinel-group/sentinel-awesome](https://github.com/sentine
- [Guideline: 从 Hystrix 迁移到 Sentinel](https://github.com/alibaba/Sentinel/wiki/Guideline:-%E4%BB%8E-Hystrix-%E8%BF%81%E7%A7%BB%E5%88%B0-Sentinel) by [Eric Zhao](https://github.com/sczyh30)
- [Sentinel 控制台监控数据持久化【MySQL】(Spring Data JPA)](https://www.cnblogs.com/cdfive2018/p/9838577.html) by [cdfive](https://github.com/cdfive)
- [Sentinel 控制台监控数据持久化【InfluxDB】](https://www.cnblogs.com/cdfive2018/p/9914838.html) by [cdfive](https://github.com/cdfive)
-- [Sentinel一体化监控解决方案 CrateDB+Grafana](https://blog.csdn.net/huyong1990/article/details/82392386) by [Young Hu](https://github.com/YoungHu)
\ No newline at end of file
+- [Sentinel一体化监控解决方案 CrateDB+Grafana](https://blog.csdn.net/huyong1990/article/details/82392386) by [Young Hu](https://github.com/YoungHu)
+- [Sentinel 原理-全解析](https://mp.weixin.qq.com/s/7_pCkamNv0269e5l9_Wz7w) by [houyi](https://github.com/all4you)
+- [Sentinel 原理-调用链](https://mp.weixin.qq.com/s/UEzwD22YC6jpp02foNSXnw) by [houyi](https://github.com/all4you)
+- [Sentinel 原理-滑动窗口](https://mp.weixin.qq.com/s/B1_7Kb_CxeKEAv43kdCWOA) by [houyi](https://github.com/all4you)
+- [Sentinel 实战-限流](https://mp.weixin.qq.com/s/rjyU37Dm-sxNln7GUD8tOw) by [houyi](https://github.com/all4you)
+- [Sentinel 实战-控制台](https://mp.weixin.qq.com/s/23EDFHMXLwsDqw-4O5dR5A) by [houyi](https://github.com/all4you)
+- [Sentinel 实战-规则持久化](https://mp.weixin.qq.com/s/twMFiBfRawKLR-1-N-f1yw) by [houyi](https://github.com/all4you)
\ No newline at end of file
From 4c4cb348668d21e3e34b9c55bb78429046a9faf3 Mon Sep 17 00:00:00 2001
From: cdfive <31885791+cdfive@users.noreply.github.com>
Date: Mon, 7 Jan 2019 16:17:19 +0800
Subject: [PATCH 02/39] dashboard: make fallbackToLocalWhenFail be configurable
in dashboard and fix edit rule issue when cancel (#370)
- Make fallbackToLocalWhenFail of cluster rules configurable in dashboard
- Fix edit rule when hit cancel button (object share problem solved by deep copy)
- Add metric table td header's title for friendly prompt info
---
.../resources/app/scripts/controllers/authority.js | 2 +-
.../resources/app/scripts/controllers/degrade.js | 2 +-
.../resources/app/scripts/controllers/flow_v1.js | 2 +-
.../resources/app/scripts/controllers/flow_v2.js | 5 +++--
.../app/scripts/controllers/param_flow.js | 2 +-
.../resources/app/scripts/controllers/system.js | 2 +-
.../app/views/dialog/flow-rule-dialog.html | 14 +++++++++++++-
.../main/webapp/resources/app/views/metric.html | 6 +++---
8 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/authority.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/authority.js
index 96ef1239d2..fb7b789daf 100644
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/authority.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/authority.js
@@ -55,7 +55,7 @@ angular.module('sentinelDashboardApp').controller('AuthorityRuleController', ['$
var authorityRuleDialog;
$scope.editRule = function (rule) {
- $scope.currentRule = rule;
+ $scope.currentRule = angular.copy(rule);
$scope.authorityRuleDialog = {
title: '编辑授权规则',
type: 'edit',
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/degrade.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/degrade.js
index 14423f6510..45773c66a0 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/degrade.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/degrade.js
@@ -45,7 +45,7 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
var degradeRuleDialog;
$scope.editRule = function (rule) {
- $scope.currentRule = rule;
+ $scope.currentRule = angular.copy(rule);
$scope.degradeRuleDialog = {
title: '编辑降级规则',
type: 'edit',
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js
index d587a13d88..643ff12d92 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js
@@ -61,7 +61,7 @@ app.controller('FlowControllerV1', ['$scope', '$stateParams', 'FlowServiceV1', '
var flowRuleDialog;
$scope.editRule = function (rule) {
- $scope.currentRule = rule;
+ $scope.currentRule = angular.copy(rule);
$scope.flowRuleDialog = {
title: '编辑流控规则',
type: 'edit',
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v2.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v2.js
index 4e11c2440b..8a98c8d507 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v2.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v2.js
@@ -61,7 +61,7 @@ app.controller('FlowControllerV2', ['$scope', '$stateParams', 'FlowServiceV2', '
var flowRuleDialog;
$scope.editRule = function (rule) {
- $scope.currentRule = rule;
+ $scope.currentRule = angular.copy(rule);
$scope.flowRuleDialog = {
title: '编辑流控规则',
type: 'edit',
@@ -88,7 +88,8 @@ app.controller('FlowControllerV2', ['$scope', '$stateParams', 'FlowServiceV2', '
limitApp: 'default',
clusterMode: false,
clusterConfig: {
- thresholdType: 0
+ thresholdType: 0,
+ fallbackToLocalWhenFail: true
}
};
$scope.flowRuleDialog = {
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/param_flow.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/param_flow.js
index 4b6f799e8f..65cf157edd 100644
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/param_flow.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/param_flow.js
@@ -129,7 +129,7 @@ angular.module('sentinelDashboardApp').controller('ParamFlowController', ['$scop
var paramFlowRuleDialog;
$scope.editRule = function (rule) {
- $scope.currentRule = rule;
+ $scope.currentRule = angular.copy(rule);
$scope.paramFlowRuleDialog = {
title: '编辑热点规则',
type: 'edit',
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/system.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/system.js
index c08d418f78..8e7ed65556 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/system.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/system.js
@@ -58,7 +58,7 @@ app.controller('SystemCtl', ['$scope', '$stateParams', 'SystemService', 'ngDialo
$scope.getMachineRules = getMachineRules;
var systemRuleDialog;
$scope.editRule = function (rule) {
- $scope.currentRule = rule;
+ $scope.currentRule = angular.copy(rule);
$scope.systemRuleDialog = {
title: '编辑系统保护规则',
type: 'edit',
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html b/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html
index bd07ac3611..b7dd29c502 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html
+++ b/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html
@@ -53,7 +53,9 @@
+
@@ -66,6 +68,16 @@
+
+
+
+
+
+
+
@@ -133,4 +145,4 @@
-
+
\ No newline at end of file
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html b/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html
index ed08eb7459..a77b895f0a 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html
+++ b/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html
@@ -51,9 +51,9 @@
时间
-
p_qps
-
b_qps
-
rt(ms)
+
p_qps
+
b_qps
+
rt(ms)
From d3b3d6572fc8b45ef97827e609169e24a497b858 Mon Sep 17 00:00:00 2001
From: Zhe Jiang
Date: Mon, 7 Jan 2019 16:40:35 +0800
Subject: [PATCH 03/39] dashboard: add healthCount/total information in sidebar
of Sentinel dashboard (#376)
---
.../app/scripts/directives/sidebar/sidebar.html | 1 +
.../app/scripts/directives/sidebar/sidebar.js | 13 ++++++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
index 6a030b3729..dbabfff672 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
@@ -19,6 +19,7 @@
{{entry.app}}
+ ({{entry.heathCount}}/{{entry.machines.length}})
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.js
index ce1a903003..55f63548f9 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.js
@@ -21,11 +21,22 @@ angular.module('sentinelDashboardApp')
function (data) {
if (data.code === 0) {
let initHashApp = $location.path().split('/')[3];
+ let currTime = moment(new Date()).utc().add(-1000*60*5).format('YYYY-MM-DDTHH:mm:ss')
$scope.apps = data.data;
- $scope.apps.forEach(function (item) {
+ $scope.apps = $scope.apps.map(function (item) {
if (item.app === initHashApp) {
item.active = true;
}
+ var heathCount = 0;
+ for (var i in item.machines) {
+ if (item.machines[i].timestamp>currTime) {
+ heathCount++;
+ }
+ }
+ item.heathCount = heathCount;
+ if (heathCount>0) {
+ return item;
+ }
});
}
}
From 471bdf7599f3e611623a7d3fe29d8a2500f7bf88 Mon Sep 17 00:00:00 2001
From: Eric Zhao
Date: Tue, 8 Jan 2019 09:45:16 +0800
Subject: [PATCH 04/39] dashboard: structure rearrangement and polish related
code
Signed-off-by: Eric Zhao
---
.../{view => controller}/AppController.java | 5 +--
.../AuthorityRuleController.java | 3 +-
.../DegradeController.java | 3 +-
.../{view => controller}/DemoController.java | 2 +-
.../FlowControllerV1.java | 7 ++--
.../MachineRegistryController.java | 3 +-
.../MetricController.java | 5 +--
.../ParamFlowRuleController.java | 4 ++-
.../ResourceController.java | 5 +--
.../SystemController.java | 3 +-
.../cluster/ClusterAssignController.java | 4 +--
.../cluster/ClusterConfigController.java | 4 +--
.../v2}/FlowControllerV2.java | 3 +-
.../dashboard/{view => domain}/Result.java | 2 +-
.../{view => domain}/vo/MachineInfoVo.java | 2 +-
.../{view => domain}/vo/MetricVo.java | 2 +-
.../{view => domain}/vo/ResourceVo.java | 2 +-
.../sentinel/dashboard/view/HealthCheck.java | 33 -------------------
18 files changed, 35 insertions(+), 57 deletions(-)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/AppController.java (94%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/AuthorityRuleController.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/DegradeController.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/DemoController.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/FlowControllerV1.java (97%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/MachineRegistryController.java (96%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/MetricController.java (97%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/ParamFlowRuleController.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/ResourceController.java (95%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/SystemController.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/cluster/ClusterAssignController.java (97%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller}/cluster/ClusterConfigController.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => controller/v2}/FlowControllerV2.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => domain}/Result.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => domain}/vo/MachineInfoVo.java (98%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => domain}/vo/MetricVo.java (99%)
rename sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/{view => domain}/vo/ResourceVo.java (99%)
delete mode 100755 sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/HealthCheck.java
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/AppController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/AppController.java
similarity index 94%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/AppController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/AppController.java
index 024a094e76..25e453732c 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/AppController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/AppController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.ArrayList;
import java.util.Collections;
@@ -25,7 +25,8 @@
import com.taobao.csp.sentinel.dashboard.discovery.AppInfo;
import com.taobao.csp.sentinel.dashboard.discovery.AppManagement;
import com.taobao.csp.sentinel.dashboard.discovery.MachineInfo;
-import com.taobao.csp.sentinel.dashboard.view.vo.MachineInfoVo;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
+import com.taobao.csp.sentinel.dashboard.domain.vo.MachineInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/AuthorityRuleController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/AuthorityRuleController.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/AuthorityRuleController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/AuthorityRuleController.java
index 367067b98f..1f28e9ba47 100644
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/AuthorityRuleController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/AuthorityRuleController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
@@ -24,6 +24,7 @@
import com.taobao.csp.sentinel.dashboard.client.SentinelApiClient;
import com.taobao.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
import com.taobao.csp.sentinel.dashboard.discovery.MachineInfo;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import com.taobao.csp.sentinel.dashboard.repository.rule.RuleRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/DegradeController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/DegradeController.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/DegradeController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/DegradeController.java
index 78d3ffc145..ef50d2b4f1 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/DegradeController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/DegradeController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
@@ -24,6 +24,7 @@
import com.taobao.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.taobao.csp.sentinel.dashboard.discovery.MachineInfo;
import com.taobao.csp.sentinel.dashboard.client.SentinelApiClient;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import com.taobao.csp.sentinel.dashboard.repository.rule.InMemDegradeRuleStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/DemoController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/DemoController.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/DemoController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/DemoController.java
index 8b7ab528f2..a30ea440ed 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/DemoController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/DemoController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.Random;
import java.util.concurrent.TimeUnit;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/FlowControllerV1.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/FlowControllerV1.java
similarity index 97%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/FlowControllerV1.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/FlowControllerV1.java
index dd435fe15b..94ac3e5589 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/FlowControllerV1.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/FlowControllerV1.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
@@ -23,6 +23,7 @@
import com.taobao.csp.sentinel.dashboard.client.SentinelApiClient;
import com.taobao.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.taobao.csp.sentinel.dashboard.discovery.MachineInfo;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import com.taobao.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,8 +57,8 @@ public class FlowControllerV1 {
@GetMapping("/rules")
public Result> apiQueryMachineRules(@RequestParam String app,
- @RequestParam String ip,
- @RequestParam Integer port) {
+ @RequestParam String ip,
+ @RequestParam Integer port) {
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/MachineRegistryController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/MachineRegistryController.java
similarity index 96%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/MachineRegistryController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/MachineRegistryController.java
index 5a73f5ecfd..e55f111f94 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/MachineRegistryController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/MachineRegistryController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.Date;
@@ -22,6 +22,7 @@
import com.taobao.csp.sentinel.dashboard.discovery.AppManagement;
import com.taobao.csp.sentinel.dashboard.discovery.MachineDiscovery;
import com.taobao.csp.sentinel.dashboard.discovery.MachineInfo;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/MetricController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/MetricController.java
similarity index 97%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/MetricController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/MetricController.java
index ee336664e4..9de266800b 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/MetricController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/MetricController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.ArrayList;
import java.util.Collections;
@@ -24,6 +24,7 @@
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import com.taobao.csp.sentinel.dashboard.repository.metric.MetricsRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,7 +37,7 @@
import com.alibaba.csp.sentinel.util.StringUtil;
import com.taobao.csp.sentinel.dashboard.datasource.entity.MetricEntity;
-import com.taobao.csp.sentinel.dashboard.view.vo.MetricVo;
+import com.taobao.csp.sentinel.dashboard.domain.vo.MetricVo;
/**
* @author leyou
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/ParamFlowRuleController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/ParamFlowRuleController.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/ParamFlowRuleController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/ParamFlowRuleController.java
index c24b605d85..dfe2cfba45 100644
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/ParamFlowRuleController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/ParamFlowRuleController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
@@ -30,6 +30,7 @@
import com.taobao.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity;
import com.taobao.csp.sentinel.dashboard.discovery.AppManagement;
import com.taobao.csp.sentinel.dashboard.discovery.MachineInfo;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import com.taobao.csp.sentinel.dashboard.repository.rule.RuleRepository;
import com.taobao.csp.sentinel.dashboard.util.VersionUtils;
import org.slf4j.Logger;
@@ -123,6 +124,7 @@ public Result apiAddParamFlowRule(@RequestBody ParamFlowRul
return unsupportedVersion();
}
entity.setId(null);
+ entity.getRule().setResource(entity.getResource().trim());
Date date = new Date();
entity.setGmtCreate(date);
entity.setGmtModified(date);
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/ResourceController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/ResourceController.java
similarity index 95%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/ResourceController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/ResourceController.java
index a6e16cae6c..3189923f98 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/ResourceController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/ResourceController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.List;
import java.util.stream.Collectors;
@@ -23,7 +23,8 @@
import com.taobao.csp.sentinel.dashboard.domain.ResourceTreeNode;
import com.taobao.csp.sentinel.dashboard.client.SentinelApiClient;
-import com.taobao.csp.sentinel.dashboard.view.vo.ResourceVo;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
+import com.taobao.csp.sentinel.dashboard.domain.vo.ResourceVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/SystemController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/SystemController.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/SystemController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/SystemController.java
index 17dfe83352..437b2e4e5c 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/SystemController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/SystemController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
@@ -23,6 +23,7 @@
import com.taobao.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
import com.taobao.csp.sentinel.dashboard.discovery.MachineInfo;
import com.taobao.csp.sentinel.dashboard.client.SentinelApiClient;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import com.taobao.csp.sentinel.dashboard.repository.rule.InMemSystemRuleStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/cluster/ClusterAssignController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/cluster/ClusterAssignController.java
similarity index 97%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/cluster/ClusterAssignController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/cluster/ClusterAssignController.java
index 0a91e56b4d..491386cef0 100644
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/cluster/ClusterAssignController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/cluster/ClusterAssignController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view.cluster;
+package com.taobao.csp.sentinel.dashboard.controller.cluster;
import java.util.Collections;
import java.util.Set;
@@ -24,7 +24,7 @@
import com.taobao.csp.sentinel.dashboard.domain.cluster.ClusterAppAssignResultVO;
import com.taobao.csp.sentinel.dashboard.domain.cluster.ClusterAppSingleServerAssignRequest;
import com.taobao.csp.sentinel.dashboard.service.ClusterAssignService;
-import com.taobao.csp.sentinel.dashboard.view.Result;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/cluster/ClusterConfigController.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/cluster/ClusterConfigController.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/cluster/ClusterConfigController.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/cluster/ClusterConfigController.java
index ee234e699e..bcbb3b6506 100644
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/cluster/ClusterConfigController.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/cluster/ClusterConfigController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view.cluster;
+package com.taobao.csp.sentinel.dashboard.controller.cluster;
import java.util.List;
import java.util.Optional;
@@ -37,7 +37,7 @@
import com.taobao.csp.sentinel.dashboard.service.ClusterConfigService;
import com.taobao.csp.sentinel.dashboard.util.ClusterEntityUtils;
import com.taobao.csp.sentinel.dashboard.util.VersionUtils;
-import com.taobao.csp.sentinel.dashboard.view.Result;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/FlowControllerV2.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/FlowControllerV2.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java
index c3bf5bf96d..fb9ecb49c8 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/FlowControllerV2.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.controller.v2;
import java.util.Date;
import java.util.List;
@@ -24,6 +24,7 @@
import com.taobao.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter;
import com.taobao.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.taobao.csp.sentinel.dashboard.rule.DynamicRulePublisher;
+import com.taobao.csp.sentinel.dashboard.domain.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/Result.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/Result.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/Result.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/Result.java
index 5f8ee7467b..23d8d84dda 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/Result.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/Result.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view;
+package com.taobao.csp.sentinel.dashboard.domain;
/**
* @author leyou
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/MachineInfoVo.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/MachineInfoVo.java
similarity index 98%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/MachineInfoVo.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/MachineInfoVo.java
index 4e9af36785..835237e101 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/MachineInfoVo.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/MachineInfoVo.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view.vo;
+package com.taobao.csp.sentinel.dashboard.domain.vo;
import java.util.ArrayList;
import java.util.Date;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/MetricVo.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/MetricVo.java
similarity index 99%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/MetricVo.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/MetricVo.java
index c2e73713b3..460580c660 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/MetricVo.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/MetricVo.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view.vo;
+package com.taobao.csp.sentinel.dashboard.domain.vo;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/ResourceVo.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/ResourceVo.java
similarity index 99%
rename from sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/ResourceVo.java
rename to sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/ResourceVo.java
index 1870e6aaad..a5fb302eca 100755
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/vo/ResourceVo.java
+++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/domain/vo/ResourceVo.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.taobao.csp.sentinel.dashboard.view.vo;
+package com.taobao.csp.sentinel.dashboard.domain.vo;
import java.util.ArrayList;
import java.util.List;
diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/HealthCheck.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/HealthCheck.java
deleted file mode 100755
index 2afb48c7e4..0000000000
--- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/view/HealthCheck.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.taobao.csp.sentinel.dashboard.view;
-
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-@Controller
-public class HealthCheck {
- /**
- * 健康检查
- */
- @GetMapping("/health")
- public
- @ResponseBody
- String checkPreload() {
- return "success";
- }
-}
From 883565a5f662ccf1e85dfbfadf7ad8b434cc93d6 Mon Sep 17 00:00:00 2001
From: Arlmls <23259825+Arlmls@users.noreply.github.com>
Date: Wed, 9 Jan 2019 17:16:32 +0800
Subject: [PATCH 05/39] dashboard: change text of p_qps and b_qps to be more
intuitive in monitoring page (#398)
---
.../main/webapp/resources/app/scripts/controllers/metric.js | 4 ++--
.../src/main/webapp/resources/app/views/metric.html | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/metric.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/metric.js
index 7986d2f6ff..2fa4b92fb1 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/metric.js
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/metric.js
@@ -131,10 +131,10 @@ app.controller('MetricCtl', ['$scope', '$stateParams', 'MetricService', '$interv
allowAllCanceled: true,
itemFormatter: function (val) {
if ('passQps' === val) {
- return 'p_qps';
+ return 'p_qps(通过 QPS)';
}
if ('blockQps' === val) {
- return 'b_qps';
+ return 'b_qps(拒绝 QPS)';
}
return val;
},
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html b/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html
index a77b895f0a..d248bebf5f 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html
+++ b/sentinel-dashboard/src/main/webapp/resources/app/views/metric.html
@@ -51,9 +51,9 @@
From 219877d80432341a170a5c05131221d76c5af982 Mon Sep 17 00:00:00 2001
From: moon tiger
Date: Sat, 12 Jan 2019 10:16:12 +0800
Subject: [PATCH 07/39] Add adapter support for Zuul 1.x (#188)
- implement `SentinelPreFilter`, `SentinelPostFilter` and `SentinelErrorFilter`
- support fallback
---
sentinel-adapter/pom.xml | 7 +-
.../sentinel-zuul-adapter/README.md | 148 +++++++++++++++++
.../sentinel-zuul-adapter/pom.xml | 48 ++++++
.../adapter/zuul/constants/ZuulConstant.java | 62 +++++++
.../adapter/zuul/fallback/BlockResponse.java | 67 ++++++++
.../DefaultBlockFallbackProvider.java | 43 +++++
.../fallback/DefaultRequestOriginParser.java | 13 ++
.../zuul/fallback/DefaultUrlCleaner.java | 27 +++
.../zuul/fallback/RequestOriginParser.java | 34 ++++
.../adapter/zuul/fallback/UrlCleaner.java | 31 ++++
.../fallback/ZuulBlockFallbackManager.java | 57 +++++++
.../fallback/ZuulBlockFallbackProvider.java | 40 +++++
.../zuul/filters/AbstractSentinelFilter.java | 46 +++++
.../zuul/filters/SentinelErrorFilter.java | 81 +++++++++
.../zuul/filters/SentinelPostFilter.java | 60 +++++++
.../zuul/filters/SentinelPreFilter.java | 112 +++++++++++++
.../properties/SentinelZuulProperties.java | 80 +++++++++
.../adapter/zuul/util/FilterUtil.java | 157 ++++++++++++++++++
.../ZuulBlockFallbackManagerTest.java | 62 +++++++
.../ZuulBlockFallbackProviderTest.java | 61 +++++++
.../zuul/filters/SentinelErrorFilterTest.java | 56 +++++++
.../zuul/filters/SentinelPostFilterTest.java | 45 +++++
.../zuul/filters/SentinelPreFilterTest.java | 106 ++++++++++++
23 files changed, 1442 insertions(+), 1 deletion(-)
create mode 100755 sentinel-adapter/sentinel-zuul-adapter/README.md
create mode 100755 sentinel-adapter/sentinel-zuul-adapter/pom.xml
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/constants/ZuulConstant.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/BlockResponse.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultBlockFallbackProvider.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultRequestOriginParser.java
create mode 100755 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultUrlCleaner.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/RequestOriginParser.java
create mode 100755 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/UrlCleaner.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManager.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProvider.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/AbstractSentinelFilter.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilter.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilter.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilter.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/properties/SentinelZuulProperties.java
create mode 100755 sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/util/FilterUtil.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManagerTest.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProviderTest.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilterTest.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilterTest.java
create mode 100644 sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilterTest.java
diff --git a/sentinel-adapter/pom.xml b/sentinel-adapter/pom.xml
index cfb8d5779d..04a8a4ea18 100755
--- a/sentinel-adapter/pom.xml
+++ b/sentinel-adapter/pom.xml
@@ -18,6 +18,7 @@
sentinel-web-servletsentinel-dubbo-adaptersentinel-grpc-adapter
+ sentinel-zuul-adapter
@@ -32,7 +33,11 @@
sentinel-extension${project.version}
-
+
+ com.alibaba.csp
+ sentinel-web-servlet
+ ${project.version}
+ junitjunit
diff --git a/sentinel-adapter/sentinel-zuul-adapter/README.md b/sentinel-adapter/sentinel-zuul-adapter/README.md
new file mode 100755
index 0000000000..dde1c4ebcb
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/README.md
@@ -0,0 +1,148 @@
+# Sentinel Zuul Adapter
+
+Zuul does not provide rateLimit function, If use default `SentinelRibbonFilter` route filter. it wrapped by Hystrix Command. so only provide Service level
+circuit protect.
+
+Sentinel can provide `ServiceId` level and `API Path` level flow control for zuul gateway service.
+
+*Note*: this project is for zuul 1.
+
+## How to use
+
+1. Add maven dependency
+
+```xml
+
+ com.alibaba.csp
+ sentinel-zuul-adapter
+ x.y.z
+
+
+```
+
+2. Register filters
+
+```java
+// get registry
+final FilterRegistry r = FilterRegistry.instance();
+// this is property config. set filter ennable
+SentinelZuulProperties properties = new SentinelZuulProperties();
+properties.setEnabled(true);
+// set url cleaner, here use default
+DefaultUrlCleaner defaultUrlCleaner = new DefaultUrlCleaner();
+// set origin parser. here use default
+DefaultRequestOriginParser defaultRequestOriginParser = new DefaultRequestOriginParser();
+
+// register filters. you must register all three filters.
+SentinelPreFilter sentinelPreFilter = new SentinelPreFilter(properties, defaultUrlCleaner, defaultRequestOriginParser);
+r.put("sentinelPreFilter", sentinelPreFilter);
+SentinelPostFilter postFilter = new SentinelPostFilter(properties);
+r.put("sentinelPostFilter", postFilter);
+SentinelErrorFilter errorFilter = new SentinelErrorFilter(properties);
+r.put("sentinelErrorFilter", errorFilter);
+```
+
+## How it works
+
+As Zuul run as per thread per connection block model, we add filters around `route Filter` to trace sentinel statistics.
+
+- `SentinelPreFilter`: Get an entry of resource,the first order is **ServiceId**(the key in RequestContext is `serviceId`, this can set in own custom filter), then **API Path**.
+- `SentinelPostFilter`: When success response,exit entry.
+- `SentinelPreFilter`: When get an `Exception`, trace the exception and exit context.
+
+
+the order of Filter can be changed in property:
+
+
+
+Filters create structure like:
+
+
+```bash
+
+EntranceNode: machine-root(t:3 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+-EntranceNode: coke(t:2 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+--coke(t:2 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+---/coke/coke(t:0 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+-EntranceNode: sentinel_default_context(t:0 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+-EntranceNode: book(t:1 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+--book(t:1 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+---/book/coke(t:0 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)
+
+```
+
+`book` and `coke` are serviceId.
+
+`---/book/coke` is api path, the real uri is `/coke`.
+
+
+## Integration with Sentinel DashBord
+
+1. Start [Sentinel DashBord](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0).
+
+2. Sentinel has full rule config features. see [Dynamic-Rule-Configuration](https://github.com/alibaba/Sentinel/wiki/Dynamic-Rule-Configuration)
+
+## Fallbacks
+
+Implements `SentinelFallbackProvider` to define your own Fallback Provider when Sentinel Block Exception throwing. the default
+Fallback Provider is `DefaultBlockFallbackProvider`.
+
+By default Fallback route is `ServiveId + URI PATH`, example `/book/coke`, first `book` is serviceId, `/coke` is URI PATH. so that both
+can be needed.
+
+Here is an example:
+
+```java
+
+// custom provider
+public class MyBlockFallbackProvider implements ZuulBlockFallbackProvider {
+
+ private Logger logger = LoggerFactory.getLogger(DefaultBlockFallbackProvider.class);
+
+ // you can define root as service level
+ @Override
+ public String getRoute() {
+ return "/coke/coke";
+ }
+
+ @Override
+ public BlockResponse fallbackResponse(String route, Throwable cause) {
+ RecordLog.info(String.format("[Sentinel DefaultBlockFallbackProvider] Run fallback route: %s", route));
+ if (cause instanceof BlockException) {
+ return new BlockResponse(429, "Sentinel block exception", route);
+ } else {
+ return new BlockResponse(500, "System Error", route);
+ }
+ }
+ }
+
+ // register fallback
+ ZuulBlockFallbackManager.registerProvider(new MyBlockFallbackProvider());
+
+```
+
+Default block response
+
+```json
+
+{
+ "code":429,
+ "message":"Sentinel block exception",
+ "route":"/"
+}
+```
+
+## Origin parser
+
+自定义解析URL
+
+```java
+
+public class DefaultRequestOriginParser implements RequestOriginParser {
+ @Override
+ public String parseOrigin(HttpServletRequest request) {
+ return "";
+ }
+}
+
+```
diff --git a/sentinel-adapter/sentinel-zuul-adapter/pom.xml b/sentinel-adapter/sentinel-zuul-adapter/pom.xml
new file mode 100755
index 0000000000..bf2c237368
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ sentinel-adapter
+ com.alibaba.csp
+ 1.4.2-SNAPSHOT
+
+ 4.0.0
+ sentinel-zuul-adapter
+ jar
+
+
+ 1.3.1
+ 3.1.0
+
+
+
+
+ com.alibaba.csp
+ sentinel-core
+
+
+ com.netflix.zuul
+ zuul-core
+ ${zuul.version}
+ provided
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ javax.servlet
+ javax.servlet-api
+ ${servlet.api.version}
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/constants/ZuulConstant.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/constants/ZuulConstant.java
new file mode 100644
index 0000000000..244fbf4ae8
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/constants/ZuulConstant.java
@@ -0,0 +1,62 @@
+/*
+ * 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.adapter.zuul.constants;
+
+import com.netflix.zuul.ZuulFilter;
+
+/**
+ * @author tiger
+ */
+public class ZuulConstant {
+
+ /**
+ * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in load balancer.
+ */
+ public static final String SERVICE_ID_KEY = "serviceId";
+
+ /**
+ * {@link ZuulFilter#filterType()} error type.
+ */
+ public static final String ERROR_TYPE = "error";
+
+ /**
+ * {@link ZuulFilter#filterType()} post type.
+ */
+ public static final String POST_TYPE = "post";
+
+ /**
+ * {@link ZuulFilter#filterType()} pre type.
+ */
+ public static final String PRE_TYPE = "pre";
+
+ /**
+ * {@link ZuulFilter#filterType()} route type.
+ */
+ public static final String ROUTE_TYPE = "route";
+
+ /**
+ * Filter Order for SEND_RESPONSE_FILTER_ORDER
+ */
+ public static final int SEND_RESPONSE_FILTER_ORDER = 1000;
+
+ /**
+ * Zuul use Sentinel as default context when serviceId is empty.
+ */
+ public static final String ZUUL_DEFAULT_CONTEXT = "zuul_default_context";
+
+ private ZuulConstant(){}
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/BlockResponse.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/BlockResponse.java
new file mode 100644
index 0000000000..6fd617fd10
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/BlockResponse.java
@@ -0,0 +1,67 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+/**
+ * Fall back response for {@link com.alibaba.csp.sentinel.slots.block.BlockException}
+ *
+ * @author tiger
+ */
+public class BlockResponse {
+ private int code;
+ private String message;
+ private String route;
+
+ public BlockResponse(int code, String message, String route) {
+ this.code = code;
+ this.message = message;
+ this.route = route;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getRoute() {
+ return route;
+ }
+
+ public void setRoute(String route) {
+ this.route = route;
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ "\"code\":" + code +
+ ", \"message\":" + "\"" + message + "\"" +
+ ", \"route\":" + "\"" + route + "\"" +
+ '}';
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultBlockFallbackProvider.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultBlockFallbackProvider.java
new file mode 100644
index 0000000000..432db872b1
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultBlockFallbackProvider.java
@@ -0,0 +1,43 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+
+/**
+ * Default Fallback provider for sentinel {@link BlockException}, {@literal *} meant for all routes.
+ *
+ * @author tiger
+ */
+public class DefaultBlockFallbackProvider implements ZuulBlockFallbackProvider {
+
+ @Override
+ public String getRoute() {
+ return "*";
+ }
+
+ @Override
+ public BlockResponse fallbackResponse(String route, Throwable cause) {
+ RecordLog.info(String.format("[Sentinel DefaultBlockFallbackProvider] Run fallback route: %s", route));
+ if (cause instanceof BlockException) {
+ return new BlockResponse(429, "Sentinel block exception", route);
+ } else {
+ return new BlockResponse(500, "System Error", route);
+ }
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultRequestOriginParser.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultRequestOriginParser.java
new file mode 100644
index 0000000000..45dba4d705
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultRequestOriginParser.java
@@ -0,0 +1,13 @@
+package com.alibaba.csp.sentinel.adapter.zuul.fallback;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author tiger
+ */
+public class DefaultRequestOriginParser implements RequestOriginParser {
+ @Override
+ public String parseOrigin(HttpServletRequest request) {
+ return "";
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultUrlCleaner.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultUrlCleaner.java
new file mode 100755
index 0000000000..097808204e
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/DefaultUrlCleaner.java
@@ -0,0 +1,27 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+/***
+ * @author tiger
+ */
+public class DefaultUrlCleaner implements UrlCleaner {
+
+ @Override
+ public String clean(String originUrl) {
+ return originUrl;
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/RequestOriginParser.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/RequestOriginParser.java
new file mode 100644
index 0000000000..20f6d744a2
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/RequestOriginParser.java
@@ -0,0 +1,34 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * The origin parser parses request origin (e.g. IP, user, appName) from HTTP request.
+ *
+ * @author tiger
+ */
+public interface RequestOriginParser {
+
+ /**
+ * Parse the origin from given HTTP request.
+ *
+ * @param request HTTP request
+ * @return parsed origin
+ */
+ String parseOrigin(HttpServletRequest request);
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/UrlCleaner.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/UrlCleaner.java
new file mode 100755
index 0000000000..d6b9a33b46
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/UrlCleaner.java
@@ -0,0 +1,31 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+/***
+ * @author tiger
+ */
+public interface UrlCleaner {
+
+ /***
+ *
Process the url. Some path variables should be handled and unified.
+ *
e.g. collect_item_relation--10200012121-.html will be converted to collect_item_relation.html
+ *
+ * @param originUrl original url
+ * @return processed url
+ */
+ String clean(String originUrl);
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManager.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManager.java
new file mode 100644
index 0000000000..2760acff6b
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManager.java
@@ -0,0 +1,57 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This provide fall back class manager.
+ *
+ * @author tiger
+ */
+public class ZuulBlockFallbackManager {
+
+ private static Map fallbackProviderCache = new HashMap();
+
+ private static ZuulBlockFallbackProvider defaultFallbackProvider = new DefaultBlockFallbackProvider();
+
+ /**
+ * Register special provider for different route.
+ */
+ public static synchronized void registerProvider(ZuulBlockFallbackProvider provider) {
+ String route = provider.getRoute();
+ if ("*".equals(route) || route == null) {
+ defaultFallbackProvider = provider;
+ } else {
+ fallbackProviderCache.put(route, provider);
+ }
+ }
+
+ public static ZuulBlockFallbackProvider getFallbackProvider(String route) {
+ ZuulBlockFallbackProvider provider = fallbackProviderCache.get(route);
+ if (provider == null) {
+ provider = defaultFallbackProvider;
+ }
+ return provider;
+ }
+
+ public synchronized static void clear(){
+ fallbackProviderCache.clear();
+ }
+
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProvider.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProvider.java
new file mode 100644
index 0000000000..e6b3acb0c8
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProvider.java
@@ -0,0 +1,40 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+/**
+ * This interface is compatible for different spring cloud version.
+ *
+ * @author tiger
+ */
+public interface ZuulBlockFallbackProvider {
+
+ /**
+ * The route this fallback will be used for.
+ * @return The route the fallback will be used for.
+ */
+ String getRoute();
+
+ /**
+ * Provides a fallback response based on the cause of the failed execution.
+ *
+ * @param route The route the fallback is for
+ * @param cause cause of the main method failure, may be null
+ * @return the fallback response
+ */
+ BlockResponse fallbackResponse(String route, Throwable cause);
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/AbstractSentinelFilter.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/AbstractSentinelFilter.java
new file mode 100644
index 0000000000..0becdf53d3
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/AbstractSentinelFilter.java
@@ -0,0 +1,46 @@
+/*
+ * 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.adapter.zuul.filters;
+
+import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties;
+import com.alibaba.csp.sentinel.util.AssertUtil;
+import com.netflix.zuul.ZuulFilter;
+
+/**
+ * Abstract class for sentinel filters.
+ *
+ * @author tiger
+ */
+public abstract class AbstractSentinelFilter extends ZuulFilter {
+
+ private final SentinelZuulProperties sentinelZuulProperties;
+
+ public SentinelZuulProperties getSentinelZuulProperties() {
+ return sentinelZuulProperties;
+ }
+
+ public AbstractSentinelFilter(SentinelZuulProperties sentinelZuulProperties) {
+ AssertUtil.notNull(sentinelZuulProperties,"SentinelZuulProperties can not be null");
+ this.sentinelZuulProperties = sentinelZuulProperties;
+ }
+
+ @Override
+ public boolean shouldFilter() {
+ return sentinelZuulProperties.isEnabled();
+ }
+
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilter.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilter.java
new file mode 100644
index 0000000000..dc192dba5a
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilter.java
@@ -0,0 +1,81 @@
+/*
+ * 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.adapter.zuul.filters;
+
+import com.alibaba.csp.sentinel.Tracer;
+import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.ERROR_TYPE;
+
+/**
+ * This filter track routing exception and exit entry;
+ *
+ * @author tiger
+ */
+public class SentinelErrorFilter extends AbstractSentinelFilter {
+
+ public SentinelErrorFilter(SentinelZuulProperties sentinelZuulProperties) {
+ super(sentinelZuulProperties);
+ }
+
+ @Override
+ public String filterType() {
+ return ERROR_TYPE;
+ }
+
+ @Override
+ public boolean shouldFilter() {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ return getSentinelZuulProperties().isEnabled() && ctx.getThrowable() != null;
+ }
+
+ @Override
+ public int filterOrder() {
+ return getSentinelZuulProperties().getOrder().getError();
+ }
+
+ /**
+ * Trace not {@link BlockException} ex.
+ * While loop will exit all entries,
+ * Case serviceId and URL entry twice in {@link SentinelPreFilter}.
+ * The ContextUtil.getContext().getCurEntry() will exit from inner to outer.
+ */
+ @Override
+ public Object run() throws ZuulException {
+ try {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ Throwable throwable = ctx.getThrowable();
+ if (throwable != null) {
+ if (!BlockException.isBlockException(throwable)) {
+ Tracer.trace(throwable.getCause());
+ RecordLog.info("[Sentinel Error Filter] Trace cause", throwable.getCause());
+ }
+ }
+ } finally {
+ while (ContextUtil.getContext() != null && ContextUtil.getContext().getCurEntry() != null) {
+ ContextUtil.getContext().getCurEntry().exit();
+ }
+ ContextUtil.exit();
+ }
+ return null;
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilter.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilter.java
new file mode 100644
index 0000000000..9159489c1c
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilter.java
@@ -0,0 +1,60 @@
+/*
+ * 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.adapter.zuul.filters;
+
+import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.netflix.zuul.exception.ZuulException;
+
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.POST_TYPE;
+
+/**
+ * This filter do success routing RT statistic and exit {@link com.alibaba.csp.sentinel.Entry}
+ *
+ * @author tiger
+ */
+public class SentinelPostFilter extends AbstractSentinelFilter {
+
+ public SentinelPostFilter(SentinelZuulProperties sentinelZuulProperties) {
+ super(sentinelZuulProperties);
+ }
+
+ @Override
+ public String filterType() {
+ return POST_TYPE;
+ }
+
+ @Override
+ public int filterOrder() {
+ return getSentinelZuulProperties().getOrder().getPost();
+ }
+
+ /**
+ * While loop will exit all entries,
+ * Case serviceId and URL entry twice in {@link SentinelPreFilter}.
+ * The ContextUtil.getContext().getCurEntry() will exit from inner to outer.
+ */
+ @Override
+ public Object run() throws ZuulException {
+ while (ContextUtil.getContext() != null && ContextUtil.getContext().getCurEntry() != null) {
+ ContextUtil.getContext().getCurEntry().exit();
+ }
+ ContextUtil.exit();
+ return null;
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilter.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilter.java
new file mode 100644
index 0000000000..7ef2c787a2
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilter.java
@@ -0,0 +1,112 @@
+/*
+ * 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.adapter.zuul.filters;
+
+import com.alibaba.csp.sentinel.EntryType;
+import com.alibaba.csp.sentinel.SphU;
+import com.alibaba.csp.sentinel.adapter.zuul.fallback.*;
+import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties;
+import com.alibaba.csp.sentinel.adapter.zuul.util.FilterUtil;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.alibaba.csp.sentinel.util.AssertUtil;
+import com.alibaba.csp.sentinel.util.StringUtil;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+
+import javax.servlet.http.HttpServletRequest;
+
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.PRE_TYPE;
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.SERVICE_ID_KEY;
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.ZUUL_DEFAULT_CONTEXT;
+
+/**
+ * This pre filter get an entry of resource,the first order is ServiceId, then API Path.
+ * When get a BlockException run fallback logic.
+ *
+ * @author tiger
+ */
+public class SentinelPreFilter extends AbstractSentinelFilter {
+
+ private final UrlCleaner urlCleaner;
+
+ private final RequestOriginParser requestOriginParser;
+
+ public SentinelPreFilter(SentinelZuulProperties sentinelZuulProperties,
+ UrlCleaner urlCleaner,
+ RequestOriginParser requestOriginParser) {
+ super(sentinelZuulProperties);
+ AssertUtil.notNull(urlCleaner, "UrlCleaner can not be null");
+ AssertUtil.notNull(requestOriginParser, "RequestOriginParser can not be null");
+ this.urlCleaner = urlCleaner;
+ this.requestOriginParser = requestOriginParser;
+ }
+
+ @Override
+ public String filterType() {
+ return PRE_TYPE;
+ }
+
+ /**
+ * This run before route filter so we can get more accurate RT time.
+ */
+ @Override
+ public int filterOrder() {
+ return getSentinelZuulProperties().getOrder().getPre();
+ }
+
+ @Override
+ public Object run() throws ZuulException {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ String origin = parseOrigin(ctx.getRequest());
+ String serviceTarget = (String) ctx.get(SERVICE_ID_KEY);
+ // When serviceId blocked first get the service level fallback provider.
+ String fallBackRoute = serviceTarget;
+ try {
+ if (StringUtil.isNotEmpty(serviceTarget)) {
+ RecordLog.info(String.format("[Sentinel Pre Filter] Origin: %s enter ServiceId: %s", origin, serviceTarget));
+ ContextUtil.enter(serviceTarget, origin);
+ SphU.entry(serviceTarget, EntryType.IN);
+ } else {
+ RecordLog.info("[Sentinel Pre Filter] ServiceId is empty");
+ ContextUtil.enter(ZUUL_DEFAULT_CONTEXT, origin);
+ }
+ String uriTarget = FilterUtil.filterTarget(ctx.getRequest());
+ // Clean and unify the URL.
+ // For REST APIs, you have to clean the URL (e.g. `/foo/1` and `/foo/2` -> `/foo/:id`), or
+ // the amount of context and resources will exceed the threshold.
+ uriTarget = urlCleaner.clean(uriTarget);
+ fallBackRoute = uriTarget;
+ RecordLog.info(String.format("[Sentinel Pre Filter] Origin: %s enter Uri Path: %s", origin, uriTarget));
+ SphU.entry(uriTarget, EntryType.IN);
+ } catch (BlockException ex) {
+ RecordLog.warn(String.format("[Sentinel Pre Filter] Block Exception when Origin: %s enter fall back route: %s", origin, fallBackRoute), ex);
+ ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(fallBackRoute);
+ BlockResponse blockResponse = zuulBlockFallbackProvider.fallbackResponse(fallBackRoute, ex);
+ // prevent routing from running
+ ctx.setRouteHost(null);
+ ctx.set(SERVICE_ID_KEY, null);
+ ctx.setResponseBody(blockResponse.toString());
+ }
+ return null;
+ }
+
+ private String parseOrigin(HttpServletRequest request) {
+ return requestOriginParser.parseOrigin(request);
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/properties/SentinelZuulProperties.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/properties/SentinelZuulProperties.java
new file mode 100644
index 0000000000..8e7681ed14
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/properties/SentinelZuulProperties.java
@@ -0,0 +1,80 @@
+/*
+ * 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.adapter.zuul.properties;
+
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.SEND_RESPONSE_FILTER_ORDER;
+
+/**
+ * Sentinel Spring Cloud Zuul AutoConfiguration property.
+ *
+ * @author tiger
+ */
+public class SentinelZuulProperties {
+
+ private boolean enabled = false;
+
+ private Order order = new Order();
+
+ public static class Order {
+
+ private int post = SEND_RESPONSE_FILTER_ORDER - 10;
+
+ private int pre = 10000;
+
+ private int error = -1;
+
+ public int getPost() {
+ return post;
+ }
+
+ public void setPost(int post) {
+ this.post = post;
+ }
+
+ public int getPre() {
+ return pre;
+ }
+
+ public void setPre(int pre) {
+ this.pre = pre;
+ }
+
+ public int getError() {
+ return error;
+ }
+
+ public void setError(int error) {
+ this.error = error;
+ }
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public Order getOrder() {
+ return order;
+ }
+
+ public void setOrder(Order order) {
+ this.order = order;
+ }
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/util/FilterUtil.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/util/FilterUtil.java
new file mode 100755
index 0000000000..cc00cceea8
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/zuul/util/FilterUtil.java
@@ -0,0 +1,157 @@
+/*
+ * 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.adapter.zuul.util;
+
+import com.alibaba.csp.sentinel.util.StringUtil;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Util class for web servlet filter.
+ * This is same as servlet adapter util class
+ *
+ * @author tiger
+ */
+public final class FilterUtil {
+
+ public static String filterTarget(HttpServletRequest request) {
+ String pathInfo = getResourcePath(request);
+ if (!pathInfo.startsWith("/")) {
+ pathInfo = "/" + pathInfo;
+ }
+
+ if ("/".equals(pathInfo)) {
+ return pathInfo;
+ }
+
+ // Note: pathInfo should be converted to camelCase style.
+ int lastSlashIndex = pathInfo.lastIndexOf("/");
+
+ if (lastSlashIndex >= 0) {
+ pathInfo = pathInfo.substring(0, lastSlashIndex) + "/"
+ + StringUtil.trim(pathInfo.substring(lastSlashIndex + 1));
+ } else {
+ pathInfo = "/" + StringUtil.trim(pathInfo);
+ }
+
+ return pathInfo;
+ }
+
+ private static String getResourcePath(HttpServletRequest request) {
+ String pathInfo = normalizeAbsolutePath(request.getPathInfo(), false);
+ String servletPath = normalizeAbsolutePath(request.getServletPath(), pathInfo.length() != 0);
+
+ return servletPath + pathInfo;
+ }
+
+ private static String normalizeAbsolutePath(String path, boolean removeTrailingSlash) throws IllegalStateException {
+ return normalizePath(path, true, false, removeTrailingSlash);
+ }
+
+ private static String normalizePath(String path, boolean forceAbsolute, boolean forceRelative,
+ boolean removeTrailingSlash) throws IllegalStateException {
+ char[] pathChars = StringUtil.trimToEmpty(path).toCharArray();
+ int length = pathChars.length;
+
+ // Check path and slash.
+ boolean startsWithSlash = false;
+ boolean endsWithSlash = false;
+
+ if (length > 0) {
+ char firstChar = pathChars[0];
+ char lastChar = pathChars[length - 1];
+
+ startsWithSlash = firstChar == '/' || firstChar == '\\';
+ endsWithSlash = lastChar == '/' || lastChar == '\\';
+ }
+
+ StringBuilder buf = new StringBuilder(length);
+ boolean isAbsolutePath = forceAbsolute || !forceRelative && startsWithSlash;
+ int index = startsWithSlash ? 0 : -1;
+ int level = 0;
+
+ if (isAbsolutePath) {
+ buf.append("/");
+ }
+
+ while (index < length) {
+ index = indexOfSlash(pathChars, index + 1, false);
+
+ if (index == length) {
+ break;
+ }
+
+ int nextSlashIndex = indexOfSlash(pathChars, index, true);
+
+ String element = new String(pathChars, index, nextSlashIndex - index);
+ index = nextSlashIndex;
+
+ // Ignore "."
+ if (".".equals(element)) {
+ continue;
+ }
+
+ // Backtrack ".."
+ if ("..".equals(element)) {
+ if (level == 0) {
+ if (isAbsolutePath) {
+ throw new IllegalStateException(path);
+ } else {
+ buf.append("../");
+ }
+ } else {
+ buf.setLength(pathChars[--level]);
+ }
+
+ continue;
+ }
+
+ pathChars[level++] = (char)buf.length();
+ buf.append(element).append('/');
+ }
+
+ // remove the last "/"
+ if (buf.length() > 0) {
+ if (!endsWithSlash || removeTrailingSlash) {
+ buf.setLength(buf.length() - 1);
+ }
+ }
+
+ return buf.toString();
+ }
+
+ private static int indexOfSlash(char[] chars, int beginIndex, boolean slash) {
+ int i = beginIndex;
+
+ for (; i < chars.length; i++) {
+ char ch = chars[i];
+
+ if (slash) {
+ if (ch == '/' || ch == '\\') {
+ break; // if a slash
+ }
+ } else {
+ if (ch != '/' && ch != '\\') {
+ break; // if not a slash
+ }
+ }
+ }
+
+ return i;
+ }
+
+ private FilterUtil() {}
+}
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManagerTest.java b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManagerTest.java
new file mode 100644
index 0000000000..81425be222
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackManagerTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+/**
+ * @author tiger
+ */
+public class ZuulBlockFallbackManagerTest {
+
+ private String ROUTE = "/test";
+
+ private String DEFAULT_ROUTE = "*";
+
+ class MyNullResponseFallBackProvider implements ZuulBlockFallbackProvider {
+ @Override
+ public String getRoute() {
+ return ROUTE;
+ }
+
+ @Override
+ public BlockResponse fallbackResponse(String route, Throwable cause) {
+ return null;
+ }
+ }
+
+ @Test
+ public void testRegisterProvider() throws Exception {
+ MyNullResponseFallBackProvider myNullResponseFallBackProvider = new MyNullResponseFallBackProvider();
+ ZuulBlockFallbackManager.registerProvider(myNullResponseFallBackProvider);
+ Assert.assertEquals(myNullResponseFallBackProvider.getRoute(), ROUTE);
+ Assert.assertNull(myNullResponseFallBackProvider.fallbackResponse(ROUTE, new FlowException("flow ex")));
+ }
+
+ @Test
+ public void clear() {
+ MyNullResponseFallBackProvider myNullResponseFallBackProvider = new MyNullResponseFallBackProvider();
+ ZuulBlockFallbackManager.registerProvider(myNullResponseFallBackProvider);
+ Assert.assertEquals(myNullResponseFallBackProvider.getRoute(), ROUTE);
+ ZuulBlockFallbackManager.clear();
+ Assert.assertEquals(ZuulBlockFallbackManager.getFallbackProvider(ROUTE).getRoute(),DEFAULT_ROUTE);
+ }
+
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProviderTest.java b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProviderTest.java
new file mode 100644
index 0000000000..f701d4a9da
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/fallback/ZuulBlockFallbackProviderTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.adapter.zuul.fallback;
+
+import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author tiger
+ */
+public class ZuulBlockFallbackProviderTest {
+
+ private String ALL_ROUTE = "*";
+
+ @Test
+ public void testGetNullRoute() throws Exception {
+ ZuulBlockFallbackProvider fallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(null);
+ Assert.assertEquals(fallbackProvider.getRoute(), ALL_ROUTE);
+ }
+
+ @Test
+ public void testGetDefaultRoute() throws Exception {
+ ZuulBlockFallbackProvider fallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(ALL_ROUTE);
+ Assert.assertEquals(fallbackProvider.getRoute(), ALL_ROUTE);
+ }
+
+ @Test
+ public void testGetNotInCacheRoute() throws Exception {
+ ZuulBlockFallbackProvider fallbackProvider = ZuulBlockFallbackManager.getFallbackProvider("/not/in");
+ Assert.assertEquals(fallbackProvider.getRoute(), ALL_ROUTE);
+ }
+
+ @Test
+ public void testFlowControlFallbackResponse() throws Exception {
+ ZuulBlockFallbackProvider fallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(ALL_ROUTE);
+ BlockResponse clientHttpResponse = fallbackProvider.fallbackResponse(ALL_ROUTE, new FlowException("flow exception"));
+ Assert.assertEquals(clientHttpResponse.getCode(), 429);
+ }
+
+ @Test
+ public void testRuntimeExceptionFallbackResponse() throws Exception {
+ ZuulBlockFallbackProvider fallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(ALL_ROUTE);
+ BlockResponse clientHttpResponse = fallbackProvider.fallbackResponse(ALL_ROUTE, new RuntimeException());
+ Assert.assertEquals(clientHttpResponse.getCode(), 500);
+ }
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilterTest.java b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilterTest.java
new file mode 100644
index 0000000000..8f2bca89e7
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelErrorFilterTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.adapter.zuul.filters;
+
+import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties;
+import com.netflix.zuul.context.RequestContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.ERROR_TYPE;
+
+/**
+ * @author tiger
+ */
+public class SentinelErrorFilterTest {
+ @Test
+ public void testFilterType() throws Exception {
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ SentinelErrorFilter sentinelErrorFilter = new SentinelErrorFilter(properties);
+ Assert.assertEquals(sentinelErrorFilter.filterType(), ERROR_TYPE);
+ }
+
+ @Test
+ public void testShouldFilter() {
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ Assert.assertFalse(properties.isEnabled());
+ properties.setEnabled(true);
+ SentinelErrorFilter sentinelErrorFilter = new SentinelErrorFilter(properties);
+ RequestContext ctx = RequestContext.getCurrentContext();
+ ctx.setThrowable(new RuntimeException());
+ Assert.assertTrue(sentinelErrorFilter.shouldFilter());
+ }
+
+ @Test
+ public void testRun() throws Exception {
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ SentinelErrorFilter sentinelErrorFilter = new SentinelErrorFilter(properties);
+ Object result = sentinelErrorFilter.run();
+ Assert.assertNull(result);
+ }
+
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilterTest.java b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilterTest.java
new file mode 100644
index 0000000000..6ccd6cae20
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPostFilterTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.adapter.zuul.filters;
+
+import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties;
+import org.junit.Assert;
+import org.junit.Test;
+
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.POST_TYPE;
+
+/**
+ * @author tiger
+ */
+public class SentinelPostFilterTest {
+
+ @Test
+ public void testFilterType() throws Exception {
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ SentinelPostFilter sentinelPostFilter = new SentinelPostFilter(properties);
+ Assert.assertEquals(sentinelPostFilter.filterType(), POST_TYPE);
+ }
+
+ @Test
+ public void testRun() throws Exception {
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ SentinelPostFilter sentinelPostFilter = new SentinelPostFilter(properties);
+ Object result = sentinelPostFilter.run();
+ Assert.assertNull(result);
+ }
+
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilterTest.java b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilterTest.java
new file mode 100644
index 0000000000..ab71e5cfd7
--- /dev/null
+++ b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/zuul/filters/SentinelPreFilterTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.adapter.zuul.filters;
+
+import com.alibaba.csp.sentinel.adapter.zuul.fallback.DefaultRequestOriginParser;
+import com.alibaba.csp.sentinel.adapter.zuul.fallback.RequestOriginParser;
+import com.alibaba.csp.sentinel.adapter.zuul.fallback.UrlCleaner;
+import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
+import com.netflix.zuul.context.RequestContext;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import javax.servlet.http.HttpServletRequest;
+
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.PRE_TYPE;
+import static com.alibaba.csp.sentinel.adapter.zuul.constants.ZuulConstant.SERVICE_ID_KEY;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author tiger
+ */
+public class SentinelPreFilterTest {
+
+ private String SERVICE_ID = "servicea";
+
+ private String URI = "/servicea/test";
+
+ @Mock
+ private HttpServletRequest httpServletRequest;
+
+ @Mock
+ private UrlCleaner urlCleaner;
+
+ private final RequestOriginParser requestOriginParser = new DefaultRequestOriginParser();
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(httpServletRequest.getContextPath()).thenReturn("");
+ when(httpServletRequest.getPathInfo()).thenReturn(URI);
+ RequestContext requestContext = new RequestContext();
+ requestContext.set(SERVICE_ID_KEY, SERVICE_ID);
+ requestContext.setRequest(httpServletRequest);
+ RequestContext.testSetCurrentContext(requestContext);
+ }
+
+ @Test
+ public void testFilterType() throws Exception {
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ SentinelPreFilter sentinelPreFilter = new SentinelPreFilter(properties, urlCleaner, requestOriginParser);
+ Assert.assertEquals(sentinelPreFilter.filterType(), PRE_TYPE);
+ }
+
+ @Test
+ public void testRun() throws Exception {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ SentinelPreFilter sentinelPreFilter = new SentinelPreFilter(properties, urlCleaner, requestOriginParser);
+ given(urlCleaner.clean(URI)).willReturn(URI);
+ sentinelPreFilter.run();
+ Assert.assertNull(ctx.getRouteHost());
+ Assert.assertEquals(ctx.get(SERVICE_ID_KEY), SERVICE_ID);
+ }
+
+ @Test
+ public void testServiceFallBackRun() throws Exception {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ SentinelZuulProperties properties = new SentinelZuulProperties();
+ properties.setEnabled(true);
+ SentinelPreFilter sentinelPreFilter = new SentinelPreFilter(properties, urlCleaner, requestOriginParser);
+
+ given(urlCleaner.clean(URI)).willAnswer(
+ new Answer
+
+ javax.servlet
+ javax.servlet-api
+ ${servlet.api.version}
+ provided
+ com.netflix.zuulzuul-core${zuul.version}provided
+
junitjunit
@@ -37,12 +44,6 @@
mockito-coretest
-
- javax.servlet
- javax.servlet-api
- ${servlet.api.version}
- provided
-
\ No newline at end of file
From cca58497c44c822d7ebc014e1535aee47ec43a32 Mon Sep 17 00:00:00 2001
From: Eric Zhao
Date: Mon, 14 Jan 2019 14:16:58 +0800
Subject: [PATCH 09/39] Update cluster demo README and remove unused demo
Signed-off-by: Eric Zhao
---
.../sentinel-demo-cluster-embedded/README.md | 6 ++
.../demo/cluster/ClusterClientDemo.java | 62 -------------------
2 files changed, 6 insertions(+), 62 deletions(-)
create mode 100644 sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/README.md
delete mode 100644 sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java
diff --git a/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/README.md b/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/README.md
new file mode 100644
index 0000000000..95d93c0773
--- /dev/null
+++ b/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/README.md
@@ -0,0 +1,6 @@
+# Sentinel Cluster Embedded Mode Demo
+
+This demo demonstrates how to configure data source for cluster rules and configuration
+in **embedded mode**. You can start multiple `ClusterDemoApplication` instances and do cluster assignment in Sentinel dashboard or via dynamic data source.
+
+See [DemoClusterInitFunc](https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterInitFunc.java) for a sample of dynamic configuration.
\ No newline at end of file
diff --git a/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java b/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java
deleted file mode 100644
index cf0af2e9d2..0000000000
--- a/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.demo.cluster;
-
-import com.alibaba.csp.sentinel.Entry;
-import com.alibaba.csp.sentinel.EntryType;
-import com.alibaba.csp.sentinel.SphU;
-import com.alibaba.csp.sentinel.cluster.ClusterStateManager;
-import com.alibaba.csp.sentinel.init.InitExecutor;
-import com.alibaba.csp.sentinel.slots.block.BlockException;
-
-/**
- *
Run this demo with the following args: -Dproject.name=appA
- *
You need a token server running already.
- *
- * @author Eric Zhao
- */
-public class ClusterClientDemo {
-
- public static void main(String[] args) {
- InitExecutor.doInit();
-
- // Manually schedule the cluster mode to client.
- // In common, we need a scheduling system to modify the cluster mode automatically.
- // Command HTTP API: http://:/setClusterMode?mode=
- ClusterStateManager.setToClient();
-
- String resourceName = "cluster-demo-entry";
-
- // Assume we have a cluster flow rule for `demo-resource`: QPS = 5 in AVG_LOCAL mode.
- for (int i = 0; i < 10; i++) {
- tryEntry(resourceName);
- }
- }
-
- private static void tryEntry(String res) {
- Entry entry = null;
- try {
- entry = SphU.entry(res, EntryType.IN, 1, "abc", "def");
- System.out.println("Passed");
- } catch (BlockException ex) {
- ex.printStackTrace();
- } finally {
- if (entry != null) {
- entry.exit();
- }
- }
- }
-}
From 57593975f8d61e9e747b69eeebfdcbdcd1de283e Mon Sep 17 00:00:00 2001
From: kangyl <460720197@qq.com>
Date: Mon, 14 Jan 2019 17:54:31 +0800
Subject: [PATCH 10/39] Remove redundant semicolon in MetricWriter (#412)
---
.../java/com/alibaba/csp/sentinel/node/metric/MetricWriter.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricWriter.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricWriter.java
index a1ca49ff15..30fd14ee02 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricWriter.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricWriter.java
@@ -346,7 +346,6 @@ private void closeAndNewFile(String fileName) throws Exception {
outMetricBuf = new BufferedOutputStream(outMetric);
curMetricFile = new File(fileName);
String idxFile = formIndexFileName(fileName);
- ;
curMetricIndexFile = new File(idxFile);
outIndex = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(idxFile, append)));
RecordLog.info("[MetricWriter] New metric file created: " + fileName);
From f089afd8d94713821ecd208efb2fac555b40a708 Mon Sep 17 00:00:00 2001
From: kexianjun
Date: Tue, 15 Jan 2019 17:18:07 +0800
Subject: [PATCH 11/39] Fix incorrect comment in NodeSelectorSlot javadoc
(#419)
---
.../csp/sentinel/slots/nodeselector/NodeSelectorSlot.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/nodeselector/NodeSelectorSlot.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/nodeselector/NodeSelectorSlot.java
index 7b475b89f6..aad95c8a74 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/nodeselector/NodeSelectorSlot.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/nodeselector/NodeSelectorSlot.java
@@ -33,7 +33,7 @@
*
*
adding a new {@link DefaultNode} if needed as the last child in the context.
* The context's last node is the current node or the parent node of the context.
- *
setting itself to the the context current node.
+ *
setting itself to the context current node.
*
*
*
From d352f41f7827744b26b2d29519c93c92efaa195e Mon Sep 17 00:00:00 2001
From: cdfive <31885791+cdfive@users.noreply.github.com>
Date: Tue, 15 Jan 2019 22:52:41 +0800
Subject: [PATCH 12/39] dashboard: when click the first-level menu of sidebar,
don't jump to the home page (#422)
---
.../resources/app/scripts/directives/sidebar/sidebar.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
index dbabfff672..f6889213e1 100755
--- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
+++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
@@ -16,7 +16,7 @@