diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/client/SentinelApiClient.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/client/SentinelApiClient.java index 6a7194ba..ee5ec099 100755 --- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/client/SentinelApiClient.java +++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/client/SentinelApiClient.java @@ -331,6 +331,27 @@ public class SentinelApiClient { return true; } + public boolean setAuthorityRuleOfMachine(String app, String ip, int port, List rules) { + if (rules == null) { + return true; + } + if (StringUtil.isBlank(ip) || port <= 0) { + throw new IllegalArgumentException("Invalid IP or port"); + } + String data = JSON.toJSONString( + rules.stream().map(AuthorityRuleEntity::getRule).collect(Collectors.toList())); + try { + data = URLEncoder.encode(data, DEFAULT_CHARSET.name()); + } catch (UnsupportedEncodingException e) { + logger.info("Encode rule error", e); + return false; + } + String url = "http://" + ip + ":" + port + "/" + SET_RULES_PATH + "?type=" + AUTHORITY_TYPE + "&data=" + data; + String result = httpGetContent(url); + logger.info("Push authority rules: " + result); + return true; + } + public CompletableFuture setParamFlowRuleOfMachine(String app, String ip, int port, List rules) { if (rules == null) { return CompletableFuture.completedFuture(null); diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java index 9ed125f7..6c98d8c1 100644 --- a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java +++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java @@ -18,12 +18,16 @@ package com.taobao.csp.sentinel.dashboard.datasource.entity.rule; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule; import com.alibaba.csp.sentinel.util.AssertUtil; +import com.fasterxml.jackson.annotation.JsonIgnore; + /** * @author Eric Zhao * @since 0.2.1 */ public class AuthorityRuleEntity extends AbstractRuleEntity { + public AuthorityRuleEntity() {} + public AuthorityRuleEntity(AuthorityRule authorityRule) { AssertUtil.notNull(authorityRule, "Authority rule should not be null"); this.rule = authorityRule; @@ -37,14 +41,17 @@ public class AuthorityRuleEntity extends AbstractRuleEntity { return entity; } + @JsonIgnore public String getLimitApp() { return rule.getLimitApp(); } + @JsonIgnore public String getResource() { return rule.getResource(); } + @JsonIgnore public int getStrategy() { return rule.getStrategy(); } diff --git a/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/repository/rule/InMemAuthorityRuleStore.java b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/repository/rule/InMemAuthorityRuleStore.java new file mode 100644 index 00000000..e04f0b86 --- /dev/null +++ b/sentinel-dashboard/src/main/java/com/taobao/csp/sentinel/dashboard/repository/rule/InMemAuthorityRuleStore.java @@ -0,0 +1,38 @@ +/* + * 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.repository.rule; + +import java.util.concurrent.atomic.AtomicLong; + +import com.taobao.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity; +import org.springframework.stereotype.Component; + +/** + * In-memory storage for authority rules. + * + * @author Eric Zhao + * @since 0.2.1 + */ +@Component +public class InMemAuthorityRuleStore extends InMemoryRuleRepositoryAdapter { + + private static AtomicLong ids = new AtomicLong(0); + + @Override + protected long nextId() { + return ids.incrementAndGet(); + } +} 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/view/AuthorityRuleController.java index c969e7ce..367067b9 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/view/AuthorityRuleController.java @@ -15,11 +15,27 @@ */ package com.taobao.csp.sentinel.dashboard.view; +import java.util.Date; +import java.util.List; + +import com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.util.StringUtil; + 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.repository.rule.RuleRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -34,4 +50,134 @@ public class AuthorityRuleController { @Autowired private SentinelApiClient sentinelApiClient; + @Autowired + private RuleRepository repository; + + @GetMapping("/rules") + public Result> apiQueryAllRulesForMachine(@RequestParam String app, + @RequestParam String ip, + @RequestParam Integer port) { + if (StringUtil.isEmpty(app)) { + return Result.ofFail(-1, "app cannot be null or empty"); + } + if (StringUtil.isEmpty(ip)) { + return Result.ofFail(-1, "ip cannot be null or empty"); + } + if (port == null || port <= 0) { + return Result.ofFail(-1, "Invalid parameter: port"); + } + try { + List rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port); + rules = repository.saveAll(rules); + return Result.ofSuccess(rules); + } catch (Throwable throwable) { + logger.error("Error when querying authority rules", throwable); + return Result.ofFail(-1, throwable.getMessage()); + } + } + + private Result checkEntityInternal(AuthorityRuleEntity entity) { + if (entity == null) { + return Result.ofFail(-1, "bad rule body"); + } + if (StringUtil.isBlank(entity.getApp())) { + return Result.ofFail(-1, "app can't be null or empty"); + } + if (StringUtil.isBlank(entity.getIp())) { + return Result.ofFail(-1, "ip can't be null or empty"); + } + if (entity.getPort() == null || entity.getPort() <= 0) { + return Result.ofFail(-1, "port can't be null"); + } + if (entity.getRule() == null) { + return Result.ofFail(-1, "rule can't be null"); + } + if (StringUtil.isBlank(entity.getResource())) { + return Result.ofFail(-1, "resource name cannot be null or empty"); + } + if (StringUtil.isBlank(entity.getLimitApp())) { + return Result.ofFail(-1, "limitApp should be valid"); + } + if (entity.getStrategy() != RuleConstant.AUTHORITY_WHITE + && entity.getStrategy() != RuleConstant.AUTHORITY_BLACK) { + return Result.ofFail(-1, "Unknown strategy (must be blacklist or whitelist)"); + } + return null; + } + + @PostMapping("/rule") + public Result apiAddAuthorityRule(@RequestBody AuthorityRuleEntity entity) { + Result checkResult = checkEntityInternal(entity); + if (checkResult != null) { + return checkResult; + } + entity.setId(null); + Date date = new Date(); + entity.setGmtCreate(date); + entity.setGmtModified(date); + try { + entity = repository.save(entity); + } catch (Throwable throwable) { + logger.error("Failed to add authority rule", throwable); + return Result.ofThrowable(-1, throwable); + } + if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) { + logger.info("Publish authority rules failed after rule add"); + } + return Result.ofSuccess(entity); + } + + @PutMapping("/rule/{id}") + public Result apiUpdateParamFlowRule(@PathVariable("id") Long id, + @RequestBody AuthorityRuleEntity entity) { + if (id == null || id <= 0) { + return Result.ofFail(-1, "Invalid id"); + } + Result checkResult = checkEntityInternal(entity); + if (checkResult != null) { + return checkResult; + } + entity.setId(id); + Date date = new Date(); + entity.setGmtCreate(null); + entity.setGmtModified(date); + try { + entity = repository.save(entity); + if (entity == null) { + return Result.ofFail(-1, "Failed to save authority rule"); + } + } catch (Throwable throwable) { + logger.error("Failed to save authority rule", throwable); + return Result.ofThrowable(-1, throwable); + } + if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) { + logger.info("Publish authority rules failed after rule update"); + } + return Result.ofSuccess(entity); + } + + @DeleteMapping("/rule/{id}") + public Result apiDeleteRule(@PathVariable("id") Long id) { + if (id == null) { + return Result.ofFail(-1, "id cannot be null"); + } + AuthorityRuleEntity oldEntity = repository.findById(id); + if (oldEntity == null) { + return Result.ofSuccess(null); + } + try { + repository.delete(id); + } catch (Exception e) { + return Result.ofFail(-1, e.getMessage()); + } + if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) { + logger.error("Publish authority rules failed after rule delete"); + } + return Result.ofSuccess(id); + } + + private boolean publishRules(String app, String ip, Integer port) { + List rules = repository.findAllByMachine(MachineInfo.of(app, ip, port)); + return sentinelApiClient.setAuthorityRuleOfMachine(app, ip, port, rules); + } } diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js index 8784932a..430079fb 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js @@ -98,6 +98,22 @@ angular } }) + .state('dashboard.authority', { + templateUrl: 'app/views/authority.html', + url: '/authority/:app', + controller: 'AuthorityRuleController', + resolve: { + loadMyFiles: ['$ocLazyLoad', function ($ocLazyLoad) { + return $ocLazyLoad.load({ + name: 'sentinelDashboardApp', + files: [ + 'app/scripts/controllers/authority.js', + ] + }); + }] + } + }) + .state('dashboard.degrade', { templateUrl: 'app/views/degrade.html', url: '/degrade/:app', 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 new file mode 100644 index 00000000..1f190a76 --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/authority.js @@ -0,0 +1,243 @@ +/** + * Authority rule controller. + */ +angular.module('sentinelDashboardApp').controller('AuthorityRuleController', ['$scope', '$stateParams', 'AuthorityRuleService', 'ngDialog', + 'MachineService', + function ($scope, $stateParams, AuthorityRuleService, ngDialog, + MachineService) { + $scope.app = $stateParams.app; + + $scope.rulesPageConfig = { + pageSize: 10, + currentPageIndex: 1, + totalPage: 1, + totalCount: 0, + }; + $scope.macsInputConfig = { + searchField: ['text', 'value'], + persist: true, + create: false, + maxItems: 1, + render: { + item: function (data, escape) { + return '
' + escape(data.text) + '
'; + } + }, + onChange: function (value, oldValue) { + $scope.macInputModel = value; + } + }; + + function getMachineRules() { + if (!$scope.macInputModel) { + return; + } + let mac = $scope.macInputModel.split(':'); + AuthorityRuleService.queryMachineRules($scope.app, mac[0], mac[1]) + .success(function (data) { + if (data.code === 0 && data.data) { + $scope.loadError = undefined; + $scope.rules = data.data; + $scope.rulesPageConfig.totalCount = $scope.rules.length; + } else { + $scope.rules = []; + $scope.rulesPageConfig.totalCount = 0; + $scope.loadError = {message: data.msg}; + } + }) + .error((data, header, config, status) => { + $scope.loadError = {message: "未知错误"}; + }); + }; + $scope.getMachineRules = getMachineRules; + getMachineRules(); + + var authorityRuleDialog; + + $scope.editRule = function (rule) { + $scope.currentRule = rule; + $scope.authorityRuleDialog = { + title: '编辑授权规则', + type: 'edit', + confirmBtnText: '保存', + }; + authorityRuleDialog = ngDialog.open({ + template: '/app/views/dialog/authority-rule-dialog.html', + width: 680, + overlay: true, + scope: $scope + }); + }; + + $scope.addNewRule = function () { + var mac = $scope.macInputModel.split(':'); + $scope.currentRule = { + app: $scope.app, + ip: mac[0], + port: mac[1], + rule: { + strategy: 0, + limitApp: '', + } + }; + $scope.authorityRuleDialog = { + title: '新增授权规则', + type: 'add', + confirmBtnText: '新增', + showAdvanceButton: true, + }; + authorityRuleDialog = ngDialog.open({ + template: '/app/views/dialog/authority-rule-dialog.html', + width: 680, + overlay: true, + scope: $scope + }); + }; + + function checkRuleValid(rule) { + if (rule.resource === undefined || rule.resource === '') { + alert('资源名称不能为空'); + return false; + } + if (rule.limitApp === undefined || rule.limitApp === '') { + alert('流控针对应用不能为空'); + return false; + } + if (rule.strategy === undefined) { + alert('必须选择黑白名单模式'); + return false; + } + return true; + } + + $scope.saveRule = function () { + if (!checkRuleValid($scope.currentRule.rule)) { + return; + } + if ($scope.authorityRuleDialog.type === 'add') { + addNewRuleAndPush($scope.currentRule); + } else if ($scope.authorityRuleDialog.type === 'edit') { + saveRuleAndPush($scope.currentRule, true); + } + }; + + function addNewRuleAndPush(rule) { + AuthorityRuleService.addNewRule(rule).success((data) => { + if (data.success) { + getMachineRules(); + authorityRuleDialog.close(); + } else { + alert('添加规则失败:' + data.msg); + } + }).error((data) => { + if (data) { + alert('添加规则失败:' + data.msg); + } else { + alert("添加规则失败:未知错误"); + } + }); + }; + + function saveRuleAndPush(rule, edit) { + AuthorityRuleService.saveRule(rule).success(function (data) { + if (data.success) { + alert("修改规则成功"); + getMachineRules(); + if (edit) { + authorityRuleDialog.close(); + } else { + confirmDialog.close(); + } + } else { + alert('修改规则失败:' + data.msg); + } + }).error((data) => { + if (data) { + alert('修改规则失败:' + data.msg); + } else { + alert("修改规则失败:未知错误"); + } + }); + } + + function deleteRuleAndPush(entity) { + if (entity.id === undefined || isNaN(entity.id)) { + alert('规则 ID 不合法!'); + return; + } + AuthorityRuleService.deleteRule(entity).success((data) => { + if (data.code == 0) { + getMachineRules(); + confirmDialog.close(); + } else { + alert('删除规则失败:' + data.msg); + } + }).error((data) => { + if (data) { + alert('删除规则失败:' + data.msg); + } else { + alert("删除规则失败:未知错误"); + } + }); + }; + + var confirmDialog; + $scope.deleteRule = function (ruleEntity) { + $scope.currentRule = ruleEntity; + $scope.confirmDialog = { + title: '删除授权规则', + type: 'delete_rule', + attentionTitle: '请确认是否删除如下授权限流规则', + attention: '资源名: ' + ruleEntity.rule.resource + ', 流控应用: ' + ruleEntity.rule.limitApp + + ', 类型: ' + (ruleEntity.rule.strategy === 0 ? '白名单' : '黑名单'), + confirmBtnText: '删除', + }; + confirmDialog = ngDialog.open({ + template: '/app/views/dialog/confirm-dialog.html', + scope: $scope, + overlay: true + }); + }; + + $scope.confirm = function () { + if ($scope.confirmDialog.type === 'delete_rule') { + deleteRuleAndPush($scope.currentRule); + } else { + console.error('error'); + } + }; + + queryAppMachines(); + + function queryAppMachines() { + MachineService.getAppMachines($scope.app).success( + function (data) { + if (data.code == 0) { + // $scope.machines = data.data; + if (data.data) { + $scope.machines = []; + $scope.macsInputOptions = []; + data.data.forEach(function (item) { + if (item.health) { + $scope.macsInputOptions.push({ + text: item.ip + ':' + item.port, + value: item.ip + ':' + item.port + }); + } + }); + } + if ($scope.macsInputOptions.length > 0) { + $scope.macInputModel = $scope.macsInputOptions[0].value; + } + } else { + $scope.macsInputOptions = []; + } + } + ); + }; + $scope.$watch('macInputModel', function () { + if ($scope.macInputModel) { + getMachineRules(); + } + }); + }]); \ No newline at end of file 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 b85b0e64..2dac7349 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 @@ -48,6 +48,10 @@   系统规则 +
  • + +   授权规则 +
  •   机器列表 diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/authority_service.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/authority_service.js new file mode 100644 index 00000000..713e3e45 --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/authority_service.js @@ -0,0 +1,40 @@ +/** + * Authority rule service. + */ +angular.module('sentinelDashboardApp').service('AuthorityRuleService', ['$http', function ($http) { + this.queryMachineRules = function(app, ip, port) { + var param = { + app: app, + ip: ip, + port: port + }; + return $http({ + url: '/authority/rules', + params: param, + method: 'GET' + }); + }; + + this.addNewRule = function(rule) { + return $http({ + url: '/authority/rule', + data: rule, + method: 'POST' + }); + }; + + this.saveRule = function (entity) { + return $http({ + url: '/authority/rule/' + entity.id, + data: entity, + method: 'PUT' + }); + }; + + this.deleteRule = function (entity) { + return $http({ + url: '/authority/rule/' + entity.id, + method: 'DELETE' + }); + }; +}]); diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/authority.html b/sentinel-dashboard/src/main/webapp/resources/app/views/authority.html new file mode 100644 index 00000000..5dbddedd --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/authority.html @@ -0,0 +1,85 @@ +
    +
    + {{app}} +
    +
    + +
    +
    + +
    + +
    +
    +
    +
    +
    + 授权规则 + + +
    + +
    +
    + + +
    + + + + + + + + + + + + + + + + + +
    + 资源名 + + 流控应用 + + 授权类型 + + 操作 +
    {{ruleEntity.rule.resource}}{{ruleEntity.rule.limitApp }} + 白名单 + 黑名单 + + + +
    +
    + + + +
    + +
    + +
    + +
    + diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/authority-rule-dialog.html b/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/authority-rule-dialog.html new file mode 100644 index 00000000..b7051a3b --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/authority-rule-dialog.html @@ -0,0 +1,46 @@ +
    + {{authorityRuleDialog.title}} +
    +
    +
    +
    +
    + +
    + + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    +
    +  白名单   +  黑名单 +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +
    diff --git a/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js b/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js old mode 100644 new mode 100755 index 8eb155c5..cf2620c1 --- a/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js +++ b/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js @@ -1 +1 @@ -"use strict";var app;angular.module("sentinelDashboardApp",["oc.lazyLoad","ui.router","ui.bootstrap","angular-loading-bar","ngDialog","ui.bootstrap.datetimepicker","ui-notification","rzTable","angular-clipboard","selectize","angularUtils.directives.dirPagination"]).config(["$stateProvider","$urlRouterProvider","$ocLazyLoadProvider",function(e,r,a){a.config({debug:!1,events:!0}),r.otherwise("/dashboard/home"),e.state("dashboard",{url:"/dashboard",templateUrl:"app/views/dashboard/main.html",resolve:{loadMyDirectives:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/directives/header/header.js","app/scripts/directives/sidebar/sidebar.js","app/scripts/directives/sidebar/sidebar-search/sidebar-search.js"]})}]}}).state("dashboard.home",{url:"/home",templateUrl:"app/views/dashboard/home.html",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/main.js"]})}]}}).state("dashboard.flow",{templateUrl:"app/views/flow.html",url:"/flow/:app",controller:"FlowCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/flow.js"]})}]}}).state("dashboard.paramFlow",{templateUrl:"app/views/param_flow.html",url:"/paramFlow/:app",controller:"ParamFlowController",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/param_flow.js"]})}]}}).state("dashboard.degrade",{templateUrl:"app/views/degrade.html",url:"/degrade/:app",controller:"DegradeCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/degrade.js"]})}]}}).state("dashboard.system",{templateUrl:"app/views/system.html",url:"/system/:app",controller:"SystemCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/system.js"]})}]}}).state("dashboard.machine",{templateUrl:"app/views/machine.html",url:"/app/:app",controller:"MachineCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/machine.js"]})}]}}).state("dashboard.identity",{templateUrl:"app/views/identity.html",url:"/identity/:app",controller:"IdentityCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/identity.js"]})}]}}).state("dashboard.metric",{templateUrl:"app/views/metric.html",url:"/metric/:app",controller:"MetricCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/metric.js"]})}]}})}]),(app=angular.module("sentinelDashboardApp")).filter("range",[function(){return function(e,r){if(isNaN(r)||r<=0)return[];e=[];for(var a=1;a<=r;a++)e.push(a);return e}}]),(app=angular.module("sentinelDashboardApp")).service("AppService",["$http",function(e){this.getApps=function(){return e({url:"app/briefinfos.json",method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("FlowService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"flow/rules.json",params:{app:e,ip:r,port:a},method:"GET"})},this.newRule=function(e){var r={resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,strategy:e.strategy,refResource:e.refResource,controlBehavior:e.controlBehavior,warmUpPeriodSec:e.warmUpPeriodSec,maxQueueingTimeMs:e.maxQueueingTimeMs,app:e.app,ip:e.ip,port:e.port};return t({url:"/flow/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,strategy:e.strategy,refResource:e.refResource,controlBehavior:e.controlBehavior,warmUpPeriodSec:e.warmUpPeriodSec,maxQueueingTimeMs:e.maxQueueingTimeMs};return t({url:"/flow/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return t({url:"/flow/delete.json",params:r,method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("DegradeService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"degrade/rules.json",params:{app:e,ip:r,port:a},method:"GET"})},this.newRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,count:e.count,timeWindow:e.timeWindow,grade:e.grade,app:e.app,ip:e.ip,port:e.port};return t({url:"/degrade/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,timeWindow:e.timeWindow};return t({url:"/degrade/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return t({url:"/degrade/delete.json",params:r,method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("SystemService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"system/rules.json",params:{app:e,ip:r,port:a},method:"GET"})},this.newRule=function(e){var r={app:e.app,ip:e.ip,port:e.port};return 0==e.grade?r.avgLoad=e.avgLoad:1==e.grade?r.avgRt=e.avgRt:2==e.grade?r.maxThread=e.maxThread:3==e.grade&&(r.qps=e.qps),t({url:"/system/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id};return 0==e.grade?r.avgLoad=e.avgLoad:1==e.grade?r.avgRt=e.avgRt:2==e.grade?r.maxThread=e.maxThread:3==e.grade&&(r.qps=e.qps),t({url:"/system/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return t({url:"/system/delete.json",params:r,method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("MachineService",["$http",function(r){this.getAppMachines=function(e){return r({url:"app/"+e+"/machines.json",method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("IdentityService",["$http",function(t){this.fetchIdentityOfMachine=function(e,r,a){return t({url:"resource/machineResource.json",params:{ip:e,port:r,searchKey:a},method:"GET"})},this.fetchClusterNodeOfMachine=function(e,r,a){return t({url:"resource/machineResource.json",params:{ip:e,port:r,type:"cluster",searchKey:a},method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("MetricService",["$http",function(i){this.queryAppSortedIdentities=function(e){return i({url:"/metric/queryTopResourceMetric.json",params:e,method:"GET"})},this.queryByAppAndIdentity=function(e){return i({url:"/metric/queryByAppAndResource.json",params:e,method:"GET"})},this.queryByMachineAndIdentity=function(e,r,a,t,o){var s={ip:e,port:r,identity:a,startTime:t.getTime(),endTime:o.getTime()};return i({url:"/metric/queryByAppAndResource.json",params:s,method:"GET"})}}]),angular.module("sentinelDashboardApp").service("ParamFlowService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"/paramFlow/rules",params:{app:e,ip:r,port:a},method:"GET"})},this.addNewRule=function(e){return t({url:"/paramFlow/rule",data:e,method:"POST"})},this.saveRule=function(e){return t({url:"/paramFlow/rule/"+e.id,data:e,method:"PUT"})},this.deleteRule=function(e){return t({url:"/paramFlow/rule/"+e.id,method:"DELETE"})}}]); \ No newline at end of file +"use strict";var app;angular.module("sentinelDashboardApp",["oc.lazyLoad","ui.router","ui.bootstrap","angular-loading-bar","ngDialog","ui.bootstrap.datetimepicker","ui-notification","rzTable","angular-clipboard","selectize","angularUtils.directives.dirPagination"]).config(["$stateProvider","$urlRouterProvider","$ocLazyLoadProvider",function(e,r,a){a.config({debug:!1,events:!0}),r.otherwise("/dashboard/home"),e.state("dashboard",{url:"/dashboard",templateUrl:"app/views/dashboard/main.html",resolve:{loadMyDirectives:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/directives/header/header.js","app/scripts/directives/sidebar/sidebar.js","app/scripts/directives/sidebar/sidebar-search/sidebar-search.js"]})}]}}).state("dashboard.home",{url:"/home",templateUrl:"app/views/dashboard/home.html",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/main.js"]})}]}}).state("dashboard.flow",{templateUrl:"app/views/flow.html",url:"/flow/:app",controller:"FlowCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/flow.js"]})}]}}).state("dashboard.paramFlow",{templateUrl:"app/views/param_flow.html",url:"/paramFlow/:app",controller:"ParamFlowController",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/param_flow.js"]})}]}}).state("dashboard.authority",{templateUrl:"app/views/authority.html",url:"/authority/:app",controller:"AuthorityRuleController",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/authority.js"]})}]}}).state("dashboard.degrade",{templateUrl:"app/views/degrade.html",url:"/degrade/:app",controller:"DegradeCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/degrade.js"]})}]}}).state("dashboard.system",{templateUrl:"app/views/system.html",url:"/system/:app",controller:"SystemCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/system.js"]})}]}}).state("dashboard.machine",{templateUrl:"app/views/machine.html",url:"/app/:app",controller:"MachineCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/machine.js"]})}]}}).state("dashboard.identity",{templateUrl:"app/views/identity.html",url:"/identity/:app",controller:"IdentityCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/identity.js"]})}]}}).state("dashboard.metric",{templateUrl:"app/views/metric.html",url:"/metric/:app",controller:"MetricCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/metric.js"]})}]}})}]),(app=angular.module("sentinelDashboardApp")).filter("range",[function(){return function(e,r){if(isNaN(r)||r<=0)return[];e=[];for(var a=1;a<=r;a++)e.push(a);return e}}]),(app=angular.module("sentinelDashboardApp")).service("AppService",["$http",function(e){this.getApps=function(){return e({url:"app/briefinfos.json",method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("FlowService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"flow/rules.json",params:{app:e,ip:r,port:a},method:"GET"})},this.newRule=function(e){var r={resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,strategy:e.strategy,refResource:e.refResource,controlBehavior:e.controlBehavior,warmUpPeriodSec:e.warmUpPeriodSec,maxQueueingTimeMs:e.maxQueueingTimeMs,app:e.app,ip:e.ip,port:e.port};return t({url:"/flow/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,strategy:e.strategy,refResource:e.refResource,controlBehavior:e.controlBehavior,warmUpPeriodSec:e.warmUpPeriodSec,maxQueueingTimeMs:e.maxQueueingTimeMs};return t({url:"/flow/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return t({url:"/flow/delete.json",params:r,method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("DegradeService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"degrade/rules.json",params:{app:e,ip:r,port:a},method:"GET"})},this.newRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,count:e.count,timeWindow:e.timeWindow,grade:e.grade,app:e.app,ip:e.ip,port:e.port};return t({url:"/degrade/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,timeWindow:e.timeWindow};return t({url:"/degrade/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return t({url:"/degrade/delete.json",params:r,method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("SystemService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"system/rules.json",params:{app:e,ip:r,port:a},method:"GET"})},this.newRule=function(e){var r={app:e.app,ip:e.ip,port:e.port};return 0==e.grade?r.avgLoad=e.avgLoad:1==e.grade?r.avgRt=e.avgRt:2==e.grade?r.maxThread=e.maxThread:3==e.grade&&(r.qps=e.qps),t({url:"/system/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id};return 0==e.grade?r.avgLoad=e.avgLoad:1==e.grade?r.avgRt=e.avgRt:2==e.grade?r.maxThread=e.maxThread:3==e.grade&&(r.qps=e.qps),t({url:"/system/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return t({url:"/system/delete.json",params:r,method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("MachineService",["$http",function(r){this.getAppMachines=function(e){return r({url:"app/"+e+"/machines.json",method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("IdentityService",["$http",function(t){this.fetchIdentityOfMachine=function(e,r,a){return t({url:"resource/machineResource.json",params:{ip:e,port:r,searchKey:a},method:"GET"})},this.fetchClusterNodeOfMachine=function(e,r,a){return t({url:"resource/machineResource.json",params:{ip:e,port:r,type:"cluster",searchKey:a},method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("MetricService",["$http",function(s){this.queryAppSortedIdentities=function(e){return s({url:"/metric/queryTopResourceMetric.json",params:e,method:"GET"})},this.queryByAppAndIdentity=function(e){return s({url:"/metric/queryByAppAndResource.json",params:e,method:"GET"})},this.queryByMachineAndIdentity=function(e,r,a,t,o){var i={ip:e,port:r,identity:a,startTime:t.getTime(),endTime:o.getTime()};return s({url:"/metric/queryByAppAndResource.json",params:i,method:"GET"})}}]),angular.module("sentinelDashboardApp").service("ParamFlowService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"/paramFlow/rules",params:{app:e,ip:r,port:a},method:"GET"})},this.addNewRule=function(e){return t({url:"/paramFlow/rule",data:e,method:"POST"})},this.saveRule=function(e){return t({url:"/paramFlow/rule/"+e.id,data:e,method:"PUT"})},this.deleteRule=function(e){return t({url:"/paramFlow/rule/"+e.id,method:"DELETE"})}}]),angular.module("sentinelDashboardApp").service("AuthorityRuleService",["$http",function(t){this.queryMachineRules=function(e,r,a){return t({url:"/authority/rules",params:{app:e,ip:r,port:a},method:"GET"})},this.addNewRule=function(e){return t({url:"/authority/rule",data:e,method:"POST"})},this.saveRule=function(e){return t({url:"/authority/rule/"+e.id,data:e,method:"PUT"})},this.deleteRule=function(e){return t({url:"/authority/rule/"+e.id,method:"DELETE"})}}]); \ No newline at end of file diff --git a/sentinel-dashboard/src/main/webapp/resources/gulpfile.js b/sentinel-dashboard/src/main/webapp/resources/gulpfile.js index 4edc989e..64003287 100755 --- a/sentinel-dashboard/src/main/webapp/resources/gulpfile.js +++ b/sentinel-dashboard/src/main/webapp/resources/gulpfile.js @@ -51,6 +51,7 @@ const JS_APP = [ 'app/scripts/services/identityservice.js', 'app/scripts/services/metricservice.js', 'app/scripts/services/param_flow_service.js', + 'app/scripts/services/authority_service.js', ]; gulp.task('lib', function () {