├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENSE ├── README.md ├── blog_admin_provider ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── sustly │ │ ├── BlogAdminProvider.java │ │ ├── controller │ │ └── AdminController.java │ │ ├── dao │ │ └── UserDao.java │ │ └── service │ │ ├── UserService.java │ │ └── impl │ │ └── UserServiceImpl.java │ └── resources │ └── bootstrap.properties ├── blog_api ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── sustly │ ├── aspect │ └── LoggerAspect.java │ ├── dto │ ├── Pagination.java │ └── ResponseMsg.java │ ├── entry │ ├── Blog.java │ ├── BlogImage.java │ └── User.java │ ├── service │ ├── ArticleClientService.java │ ├── ArticleServiceClientFallBackFactory.java │ ├── UserClientService.java │ └── UserServiceClientFallBackFactory.java │ └── util │ ├── BeanUtil.java │ ├── DateUtil.java │ └── Md5Util.java ├── blog_article_provider ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── sustly │ │ ├── BlogArticleProvider.java │ │ ├── config │ │ └── ElasticSearchConfig.java │ │ ├── controller │ │ ├── ArticleController.java │ │ └── UploadController.java │ │ ├── dao │ │ ├── ArticleDao.java │ │ └── BlogImageDao.java │ │ ├── elastic │ │ └── ElasticsearchService.java │ │ └── service │ │ ├── ArticleService.java │ │ ├── BlogImageService.java │ │ └── impl │ │ ├── ArticleServiceImpl.java │ │ └── BlogImageServiceImpl.java │ └── resources │ └── bootstrap.properties ├── blog_consumer_feign ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── sustly │ │ ├── BlogConsumerFeign.java │ │ └── controller │ │ ├── ConsumerAdminController.java │ │ ├── ConsumerArticleController.java │ │ └── TestInfoController.java │ └── resources │ └── bootstrap.properties ├── blog_gateway ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── sustly │ │ ├── Gateway.java │ │ └── filter │ │ └── LogsFilter.java │ └── resources │ └── bootstrap.properties ├── pom.xml └── sentinel-dashboard ├── Dockerfile ├── README.md ├── Sentinel_Dashboard_Feature.md ├── pom.xml └── src └── main ├── java └── com │ └── alibaba │ └── csp │ └── sentinel │ └── dashboard │ ├── DashboardApplication.java │ ├── auth │ ├── AuthService.java │ ├── FakeAuthServiceImpl.java │ └── SimpleWebAuthServiceImpl.java │ ├── client │ ├── CommandFailedException.java │ ├── CommandNotFoundException.java │ └── SentinelApiClient.java │ ├── config │ ├── DashboardConfig.java │ └── WebConfig.java │ ├── controller │ ├── AppController.java │ ├── AuthController.java │ ├── AuthorityRuleController.java │ ├── DegradeController.java │ ├── DemoController.java │ ├── FlowControllerV1.java │ ├── MachineRegistryController.java │ ├── MetricController.java │ ├── ParamFlowRuleController.java │ ├── ResourceController.java │ ├── SystemController.java │ ├── cluster │ │ ├── ClusterAssignController.java │ │ └── ClusterConfigController.java │ ├── gateway │ │ ├── GatewayApiController.java │ │ └── GatewayFlowRuleController.java │ └── v2 │ │ └── FlowControllerV2.java │ ├── datasource │ └── entity │ │ ├── ApplicationEntity.java │ │ ├── MachineEntity.java │ │ ├── MetricEntity.java │ │ ├── MetricPositionEntity.java │ │ ├── SentinelVersion.java │ │ ├── gateway │ │ ├── ApiDefinitionEntity.java │ │ ├── ApiPredicateItemEntity.java │ │ ├── GatewayFlowRuleEntity.java │ │ └── GatewayParamFlowItemEntity.java │ │ └── rule │ │ ├── AbstractRuleEntity.java │ │ ├── AuthorityRuleEntity.java │ │ ├── DegradeRuleEntity.java │ │ ├── FlowRuleEntity.java │ │ ├── ParamFlowRuleEntity.java │ │ ├── RuleEntity.java │ │ └── SystemRuleEntity.java │ ├── discovery │ ├── AppInfo.java │ ├── AppManagement.java │ ├── MachineDiscovery.java │ ├── MachineInfo.java │ └── SimpleMachineDiscovery.java │ ├── domain │ ├── ResourceTreeNode.java │ ├── Result.java │ ├── cluster │ │ ├── ClusterAppAssignResultVO.java │ │ ├── ClusterAppFullAssignRequest.java │ │ ├── ClusterAppSingleServerAssignRequest.java │ │ ├── ClusterClientInfoVO.java │ │ ├── ClusterGroupEntity.java │ │ ├── ClusterStateSingleVO.java │ │ ├── ConnectionDescriptorVO.java │ │ ├── ConnectionGroupVO.java │ │ ├── config │ │ │ ├── ClusterClientConfig.java │ │ │ ├── ServerFlowConfig.java │ │ │ └── ServerTransportConfig.java │ │ ├── request │ │ │ ├── ClusterAppAssignMap.java │ │ │ ├── ClusterClientModifyRequest.java │ │ │ ├── ClusterModifyRequest.java │ │ │ └── ClusterServerModifyRequest.java │ │ └── state │ │ │ ├── AppClusterClientStateWrapVO.java │ │ │ ├── AppClusterServerStateWrapVO.java │ │ │ ├── ClusterClientStateVO.java │ │ │ ├── ClusterRequestLimitVO.java │ │ │ ├── ClusterServerStateVO.java │ │ │ ├── ClusterStateSimpleEntity.java │ │ │ ├── ClusterUniversalStatePairVO.java │ │ │ └── ClusterUniversalStateVO.java │ └── vo │ │ ├── MachineInfoVo.java │ │ ├── MetricVo.java │ │ ├── ResourceVo.java │ │ └── gateway │ │ ├── api │ │ ├── AddApiReqVo.java │ │ ├── ApiPredicateItemVo.java │ │ └── UpdateApiReqVo.java │ │ └── rule │ │ ├── AddFlowRuleReqVo.java │ │ ├── GatewayParamFlowItemVo.java │ │ └── UpdateFlowRuleReqVo.java │ ├── filter │ └── AuthFilter.java │ ├── metric │ └── MetricFetcher.java │ ├── repository │ ├── gateway │ │ ├── InMemApiDefinitionStore.java │ │ └── InMemGatewayFlowRuleStore.java │ ├── metric │ │ ├── InMemoryMetricsRepository.java │ │ └── MetricsRepository.java │ └── rule │ │ ├── InMemAuthorityRuleStore.java │ │ ├── InMemDegradeRuleStore.java │ │ ├── InMemFlowRuleStore.java │ │ ├── InMemParamFlowRuleStore.java │ │ ├── InMemSystemRuleStore.java │ │ ├── InMemoryRuleRepositoryAdapter.java │ │ └── RuleRepository.java │ ├── rule │ ├── DynamicRuleProvider.java │ ├── DynamicRulePublisher.java │ ├── FlowRuleApiProvider.java │ └── FlowRuleApiPublisher.java │ ├── service │ ├── ClusterAssignService.java │ ├── ClusterAssignServiceImpl.java │ └── ClusterConfigService.java │ └── util │ ├── AsyncUtils.java │ ├── ClusterEntityUtils.java │ ├── MachineUtils.java │ └── VersionUtils.java ├── resources └── application.properties └── webapp └── resources ├── .gitignore ├── .jshintrc ├── README.md ├── README_zh.md ├── app ├── scripts │ ├── app.js │ ├── controllers │ │ ├── authority.js │ │ ├── cluster_app_assign_manage.js │ │ ├── cluster_app_server_list.js │ │ ├── cluster_app_server_manage.js │ │ ├── cluster_app_server_monitor.js │ │ ├── cluster_app_token_client_list.js │ │ ├── cluster_single.js │ │ ├── degrade.js │ │ ├── flow_v1.js │ │ ├── flow_v2.js │ │ ├── gateway │ │ │ ├── api.js │ │ │ ├── flow.js │ │ │ └── identity.js │ │ ├── home.js │ │ ├── identity.js │ │ ├── login.js │ │ ├── machine.js │ │ ├── main.js │ │ ├── metric.js │ │ ├── param_flow.js │ │ └── system.js │ ├── directives │ │ ├── header │ │ │ ├── header.html │ │ │ └── header.js │ │ └── sidebar │ │ │ ├── sidebar-search │ │ │ ├── sidebar-search.html │ │ │ └── sidebar-search.js │ │ │ ├── sidebar.html │ │ │ └── sidebar.js │ ├── filters │ │ └── filters.js │ ├── libs │ │ └── treeTable.js │ └── services │ │ ├── appservice.js │ │ ├── auth_service.js │ │ ├── authority_service.js │ │ ├── cluster_state_service.js │ │ ├── degradeservice.js │ │ ├── flow_service_v1.js │ │ ├── flow_service_v2.js │ │ ├── gateway │ │ ├── api_service.js │ │ └── flow_service.js │ │ ├── identityservice.js │ │ ├── machineservice.js │ │ ├── metricservice.js │ │ ├── param_flow_service.js │ │ └── systemservice.js ├── styles │ ├── main.css │ ├── page.css │ └── timeline.css └── views │ ├── authority.html │ ├── cluster │ ├── client.html │ └── server.html │ ├── cluster_app_assign_manage.html │ ├── cluster_app_client_list.html │ ├── cluster_app_server_list.html │ ├── cluster_app_server_overview.html │ ├── cluster_single_config.html │ ├── dashboard │ ├── home.html │ └── main.html │ ├── degrade.html │ ├── dialog │ ├── authority-rule-dialog.html │ ├── cluster │ │ ├── cluster-client-config-dialog.html │ │ ├── cluster-server-assign-dialog.html │ │ └── cluster-server-connection-detail-dialog.html │ ├── confirm-dialog.html │ ├── degrade-rule-dialog.html │ ├── flow-rule-dialog.html │ ├── gateway │ │ ├── api-dialog.html │ │ └── flow-rule-dialog.html │ ├── param-flow-rule-dialog.html │ └── system-rule-dialog.html │ ├── flow_v1.html │ ├── flow_v2.html │ ├── gateway │ ├── api.html │ ├── flow.html │ └── identity.html │ ├── identity.html │ ├── login.html │ ├── machine.html │ ├── metric.html │ ├── pagination.tpl.html │ ├── param_flow.html │ └── system.html ├── assets └── img │ └── sentinel-logo.png ├── dist ├── css │ └── app.css └── js │ ├── app.js │ └── app.vendor.js ├── gulpfile.js ├── index.htm ├── index_dev.htm ├── lib ├── css │ ├── bootstrap.min.css │ └── font-awesome.min.css ├── fonts │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff └── js │ ├── angular.min.js │ ├── bootstrap.min.js │ ├── g2.min.js │ └── jquery.min.js ├── license-stat.csv ├── package-lock.json └── package.json /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up JDK 1.8 20 | uses: actions/setup-java@v1 21 | with: 22 | java-version: 1.8 23 | - name: Build with Maven 24 | run: mvn -B package --file pom.xml 25 | - name: Codecov 26 | uses: codecov/codecov-action@v1 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | /target 28 | /src/test 29 | /.idea 30 | **build/ 31 | **/target/ 32 | **/test 33 | **/*.iml 34 | /blog_vue.iml 35 | /data 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 最新 2 | ## 注意:关于部署,现在改为使用docker部署,但是使用docker部署时,如果你用的是docker中的es和mysql,他们的地址绝对不能用localhost和127.0.0.1,这样会找不到的,使用内网分配的地址才行。 3 | # blog_vue_server 4 | 5 | 6 |

关于分支

7 |
8 |

9 | master:最新内容 10 | 11 | springcloud_netflix:springcloud netflix版本,目前已经基本完善 12 | 13 | springcloud_alibaba:springcloud alibaba版本,目前已经完善 14 | 15 | springbootVersion:单机版springboot版本 16 |

17 | 18 | 博客系统的后端 19 |

使用springcloud Finchley.SR1、springboot2.0.1、mybatis、elasticsearch 6.4.2、druid、mysql5.7

20 | 21 | 本系统的前端地址 前端传送门 22 | 23 | 24 | springcloud版本 25 | 26 | 我的云服务器1G运行内存,运行不起来整个springcloud项目,所以在云服务器上运行的是以前的版本, 27 | 有兴趣的同学可以搞个运行内存大一些的云服务器 28 | 29 | 一、整体框架介绍 30 | 31 | 1.blog_eureka 32 | 33 | 使用eureka作为注册中心,注册了网关、服务提供者、服务消费者、服务发现等组件 34 | 35 | 2.blog_admin_provider_hystrix 36 | 37 | 用户登录注册服务 38 | 39 | 3.blog_article_provider_hystrix 40 | 41 | 文章管理、获取、查找等功能服务 42 | 43 | 4.blog_api 44 | 45 | 一些共用的实体类、api等 46 | 47 | 5.blog_consumer_hystrix_dashboard 48 | 49 | 服务监控 50 | 51 | 6.blog_zuul 52 | 53 | 网关 54 | 55 | 7.blog_consumer_feign 56 | 57 | 基于feign负载均衡的消费者服务 58 | 59 | -------------------------------------------------------------------------------- /blog_admin_provider/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hub.c.163.com/library/java:latest 2 | VOLUME /tmp 3 | ADD target/blog_server.jar app.jar 4 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /blog_admin_provider/src/main/java/com/sustly/BlogAdminProvider.java: -------------------------------------------------------------------------------- 1 | package com.sustly; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | 8 | @SpringBootApplication 9 | @EnableDiscoveryClient 10 | @MapperScan(basePackages = "com.systly.dao") 11 | public class BlogAdminProvider { 12 | public static void main(String[] args) { 13 | SpringApplication.run(BlogAdminProvider.class, args); 14 | } 15 | } -------------------------------------------------------------------------------- /blog_admin_provider/src/main/java/com/sustly/controller/AdminController.java: -------------------------------------------------------------------------------- 1 | package com.sustly.controller; 2 | 3 | import com.sustly.entry.User; 4 | import com.sustly.service.UserService; 5 | import com.sustly.util.DateUtil; 6 | import com.sustly.util.Md5Util; 7 | import com.sustly.dto.ResponseMsg; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | /** 14 | * @author liyue 15 | * @date 2019/5/29 9:07 16 | */ 17 | @RestController 18 | public class AdminController { 19 | 20 | private final UserService userService; 21 | 22 | @Autowired 23 | public AdminController(UserService userService) { 24 | this.userService = userService; 25 | } 26 | 27 | @PostMapping("/register") 28 | public ResponseMsg register(@RequestBody User user){ 29 | User userFind = userService.findByUsername(user.getUsername()); 30 | if(userFind != null){ 31 | return ResponseMsg.onOk(null); 32 | }else { 33 | User newUser = new User(); 34 | newUser.setUsername(user.getUsername()); 35 | newUser.setPassword(Md5Util.encrypt(user.getPassword())); 36 | newUser.setCreateTime(DateUtil.getLocalTime()); 37 | userService.save(newUser); 38 | return ResponseMsg.onOk(newUser); 39 | } 40 | 41 | 42 | } 43 | 44 | @PostMapping("/login") 45 | public ResponseMsg login(@RequestBody User user){ 46 | User userFind = userService.findByUsernameAndPassword(user); 47 | return ResponseMsg.onOk(userFind); 48 | } 49 | } -------------------------------------------------------------------------------- /blog_admin_provider/src/main/java/com/sustly/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.sustly.dao; 2 | 3 | import com.sustly.entry.User; 4 | import org.apache.ibatis.annotations.Insert; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.apache.ibatis.annotations.Select; 8 | 9 | /** 10 | * @Author: liyue 11 | * @Date: 19-9-4 下午5:13 12 | */ 13 | @Mapper 14 | public interface UserDao { 15 | 16 | @Select("select * from user where username=#{username}") 17 | User findByUsername(@Param("username") String username); 18 | 19 | @Insert("insert into user(username, password, create_time, last_login_time) values (#{username}, #{password}, #{createTime}, #{lastLoginTime})") 20 | void save(User user); 21 | 22 | @Select("select * from user where username=#{username} and password=#{password}") 23 | User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password); 24 | } 25 | -------------------------------------------------------------------------------- /blog_admin_provider/src/main/java/com/sustly/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service; 2 | 3 | import com.sustly.entry.User; 4 | 5 | /** 6 | * 7 | * @author admin 8 | */ 9 | public interface UserService { 10 | /** 11 | * findByUsername 12 | * @param username username 13 | * @return User 14 | */ 15 | User findByUsername(String username); 16 | 17 | /** 18 | * save 19 | * @param user user 20 | */ 21 | void save(User user); 22 | 23 | /** 24 | * findByUsernameAndPassword 25 | * @param user user 26 | * @return User 27 | */ 28 | User findByUsernameAndPassword(User user); 29 | } 30 | -------------------------------------------------------------------------------- /blog_admin_provider/src/main/java/com/sustly/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service.impl; 2 | 3 | import com.sustly.dao.UserDao; 4 | import com.sustly.entry.User; 5 | import com.sustly.service.UserService; 6 | import com.sustly.util.Md5Util; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | /** 12 | * @author liyue 13 | * @date 2019/5/29 9:35 14 | */ 15 | @Service 16 | @Transactional(rollbackForClassName = {"Exception.class"}) 17 | public class UserServiceImpl implements UserService { 18 | 19 | private final UserDao userDao; 20 | 21 | @Autowired 22 | public UserServiceImpl(UserDao userDao) { 23 | this.userDao = userDao; 24 | } 25 | 26 | @Override 27 | public User findByUsername(String username) { 28 | return userDao.findByUsername(username); 29 | } 30 | 31 | @Override 32 | public void save(User user) { 33 | userDao.save(user); 34 | } 35 | 36 | @Override 37 | public User findByUsernameAndPassword(User user) { 38 | return userDao.findByUsernameAndPassword(user.getUsername(), Md5Util.encrypt(user.getPassword())); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /blog_admin_provider/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | server.port=8001 2 | 3 | spring.application.name=blog-admin-provider 4 | 5 | #mybatis.configuration.map-underscore-to-camel-case=true 6 | # 7 | #spring.aop.auto=true 8 | #spring.aop.proxy-target-class=true 9 | # 10 | #spring.datasource.username=root 11 | #spring.datasource.password=123456 12 | #spring.datasource.url=jdbc:mysql://47.101.132.22:3306/blog?useSSL=false 13 | #spring.datasource.driver-class-name=com.mysql.jdbc.Driver 14 | #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 15 | 16 | #这里如果使用docker部署,一定要使用分配的内网地址,否则会无法注册 17 | spring.cloud.nacos.discovery.server-addr=localhost:8848 18 | spring.cloud.nacos.config.server-addr=http://localhost:8848 19 | spring.cloud.nacos.config.file-extension=properties 20 | spring.profiles.active=dev 21 | 22 | -------------------------------------------------------------------------------- /blog_api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blog_server 7 | com.sustly 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | blog_api 13 | 14 | 15 | 16 | org.projectlombok 17 | lombok 18 | 19 | 20 | org.springframework 21 | spring-aop 22 | 5.1.9.RELEASE 23 | 24 | 25 | com.alibaba 26 | fastjson 27 | 1.2.25 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-openfeign 32 | 33 | 34 | 35 | javax.annotation 36 | javax.annotation-api 37 | 1.3.2 38 | 39 | 40 | org.apache.commons 41 | commons-lang3 42 | 3.4 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-web 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-tomcat 51 | 52 | 53 | 54 | 55 | 56 | com.alibaba 57 | druid-spring-boot-starter 58 | 59 | 60 | 61 | org.apache.shiro 62 | shiro-core 63 | 1.2.3 64 | 65 | 66 | org.aspectj 67 | aspectjweaver 68 | 69 | 70 | javax.servlet 71 | javax.servlet-api 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/aspect/LoggerAspect.java: -------------------------------------------------------------------------------- 1 | package com.sustly.aspect; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.annotation.AfterReturning; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.aspectj.lang.annotation.Pointcut; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.Arrays; 11 | 12 | /** 13 | * @author admin 14 | */ 15 | @Component 16 | @Slf4j 17 | @Aspect 18 | public class LoggerAspect { 19 | /** 20 | * 定义切点位置 21 | */ 22 | @Pointcut(value = "execution(* com.sustly.*.*(..))") 23 | public void pointCut() { 24 | } 25 | 26 | /** 27 | * 后置通知 28 | * @param joinPoint joinPoint 29 | * @param retVal retVal 30 | */ 31 | @AfterReturning(pointcut = "pointCut()", argNames = "joinPoint, retVal", returning = "retVal") 32 | public void afterReturn(JoinPoint joinPoint, Object retVal) { 33 | String className = joinPoint.getSignature().getName(); 34 | className = className.substring(className.lastIndexOf(".") + 1); 35 | //日志记录连接点方法签名 36 | log.info(className+":"+joinPoint.getSignature().toString()); 37 | //判断参数 38 | Object[] args = joinPoint.getArgs(); 39 | StringBuilder rs = new StringBuilder(); 40 | String s = ""; 41 | if (args.length > 0) { 42 | for (Object arg : args) { 43 | if (arg == null){ 44 | continue; 45 | } 46 | if (arg instanceof Object[]) { 47 | rs.append(Arrays.toString(((Object[]) arg))).append(", "); 48 | } else { 49 | rs.append(arg.toString()).append(", "); 50 | } 51 | } 52 | s = rs.toString().substring(0, rs.toString().length() - 2); 53 | } 54 | 55 | log.info("参数:[{}] 返回值:[{}]", s ,retVal); 56 | 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/dto/Pagination.java: -------------------------------------------------------------------------------- 1 | package com.sustly.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.experimental.Accessors; 7 | 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | @Data 11 | @Accessors(chain = true) 12 | public class Pagination { 13 | private Integer count; 14 | private Object data; 15 | } 16 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/dto/ResponseMsg.java: -------------------------------------------------------------------------------- 1 | package com.sustly.dto; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @Author: liyue 7 | * @Date: 19-9-5 下午5:58 8 | */ 9 | @Data 10 | public class ResponseMsg { 11 | 12 | private boolean result; 13 | private Object data; 14 | 15 | 16 | public static ResponseMsg onOk(Object data){ 17 | ResponseMsg msg = new ResponseMsg(); 18 | msg.data = data; 19 | msg.result = true; 20 | return msg; 21 | } 22 | 23 | public static ResponseMsg onFail(Object data){ 24 | ResponseMsg msg = new ResponseMsg(); 25 | msg.data = data; 26 | msg.result = false; 27 | return msg; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/entry/Blog.java: -------------------------------------------------------------------------------- 1 | package com.sustly.entry; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author liyue 13 | * @date 2019/6/20 14:59 14 | */ 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Data 18 | @Accessors(chain = true) 19 | public class Blog { 20 | private Integer id; 21 | private String content; 22 | private String createTime; 23 | private String category; 24 | private String title; 25 | private String createUser; 26 | private Integer views; 27 | 28 | @JsonIgnore 29 | private List images; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/entry/BlogImage.java: -------------------------------------------------------------------------------- 1 | package com.sustly.entry; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | * @author liyue 10 | * @date 2019/7/5 16:27 11 | */ 12 | 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | @Data 16 | @Accessors(chain = true) 17 | public class BlogImage { 18 | private Integer id; 19 | private Integer blogId; 20 | private String imageUrl; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/entry/User.java: -------------------------------------------------------------------------------- 1 | package com.sustly.entry; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * @author liyue 13 | * @date 2019/6/20 15:02 14 | */ 15 | 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Data 19 | @Accessors(chain = true) 20 | public class User implements Serializable { 21 | private Integer id; 22 | private String username; 23 | private String password; 24 | private String createTime; 25 | private String lastLoginTime; 26 | } 27 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/service/ArticleClientService.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service; 2 | 3 | import com.sustly.dto.ResponseMsg; 4 | import com.sustly.entry.Blog; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.RequestParam; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | import org.springframework.web.multipart.MultipartFile; 14 | 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.IOException; 17 | 18 | /** 19 | * @Author: liyue 20 | * @Date: 19-9-4 下午6:10 21 | */ 22 | @FeignClient(value = "blog-article-provider", fallbackFactory = ArticleServiceClientFallBackFactory.class) 23 | public interface ArticleClientService { 24 | @PostMapping("/saveArticle") 25 | void save(@RequestBody(required = false) Blog blog); 26 | 27 | @PostMapping("/getArticle/{id}") 28 | ResponseMsg get(@PathVariable("id") Integer id); 29 | 30 | @PostMapping("/deleteArticle/{id}") 31 | void delete(@PathVariable("id") Integer id); 32 | 33 | @PostMapping("/getArticleListByTime/{page}") 34 | ResponseMsg getArticleList(@PathVariable("page") Integer page); 35 | 36 | @PostMapping("/getArticleListByTime/{username}/{page}") 37 | ResponseMsg getArticleByUserList(@PathVariable("username") String username, 38 | @PathVariable("page") Integer page); 39 | @PostMapping("/getArticleListByView/{page}") 40 | ResponseMsg getArticleListByTime(@PathVariable("page") Integer page); 41 | 42 | @PostMapping("/getArticleListByCategory/{category}/{page}") 43 | ResponseMsg getArticleListByCategory(@PathVariable("category") String category, 44 | @PathVariable("page") Integer page); 45 | @PostMapping("/view/{id}") 46 | void view(@PathVariable("id") Integer id); 47 | 48 | @PostMapping("/updateArticle") 49 | void updateArticle(@RequestBody(required = false) Blog blog)throws Exception; 50 | 51 | @PostMapping("/getArticleListBySearch/{search}/{page}") 52 | ResponseMsg getArticleListBySearch(@PathVariable("search") String search, 53 | @PathVariable("page") Integer page); 54 | @RequestMapping(value = "/uploadImg", method = RequestMethod.POST) 55 | @ResponseBody 56 | ResponseMsg uploadFile(MultipartFile image); 57 | 58 | @RequestMapping(value = "/getImg", method = RequestMethod.GET) 59 | void getFile(@RequestParam("url")String url, 60 | HttpServletResponse response) throws IOException; 61 | } 62 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/service/UserClientService.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service; 2 | 3 | import com.sustly.dto.ResponseMsg; 4 | import com.sustly.entry.User; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | 9 | /** 10 | * @Author: liyue 11 | * @Date: 19-9-4 下午5:55 12 | */ 13 | @FeignClient(value = "blog-admin-provider", fallbackFactory=UserServiceClientFallBackFactory.class) 14 | public interface UserClientService { 15 | 16 | @PostMapping("/register") 17 | ResponseMsg register(@RequestBody User user); 18 | @PostMapping("/login") 19 | ResponseMsg login(@RequestBody User user); 20 | } 21 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/service/UserServiceClientFallBackFactory.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service; 2 | 3 | import com.sustly.entry.User; 4 | import com.sustly.dto.ResponseMsg; 5 | import feign.hystrix.FallbackFactory; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @Author: liyue 11 | * @Date: 19-9-4 下午6:28 12 | */ 13 | @Component 14 | @Slf4j 15 | public class UserServiceClientFallBackFactory implements FallbackFactory { 16 | 17 | @Override 18 | public UserClientService create(Throwable throwable) { 19 | return new UserClientService() { 20 | @Override 21 | public ResponseMsg register(User user) { 22 | log.info(throwable.getMessage()); 23 | return ResponseMsg.onFail("服务器正在升级,请稍后访问!!"); 24 | } 25 | 26 | @Override 27 | public ResponseMsg login(User user) { 28 | log.info(throwable.getMessage()); 29 | return ResponseMsg.onFail("服务器正在升级,请稍后访问!"); 30 | } 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/util/BeanUtil.java: -------------------------------------------------------------------------------- 1 | package com.sustly.util; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | /** 6 | * 该工具类可实现前端传来部分属性更新,而不覆盖已有不更新的属性 7 | * @author liyue 8 | * @date 2019/3/26 16:53 9 | */ 10 | public class BeanUtil { 11 | 12 | /** 13 | * 解决更新时,源对象被覆盖 14 | * @param src 数据库查出的源对象数据 15 | * @param desc 前端传的需要更新的数据 16 | * @return 更新后的对象 17 | * @throws Exception 源对象与目标对象类型不一致 18 | */ 19 | public static Object updateBean(Object src,Object desc) throws Exception { 20 | Class srcClass = src.getClass(); 21 | Class descClass = desc.getClass(); 22 | if(!descClass.equals(srcClass)){ 23 | throw new Exception("源对象与目标对象类型不一致!"); 24 | } 25 | 26 | Field[] srcClassFields = srcClass.getDeclaredFields(); 27 | Field[] descClassFields = descClass.getDeclaredFields(); 28 | 29 | for (int i = 0; i < descClassFields.length; i++) { 30 | descClassFields[i].setAccessible(true); 31 | Object o = descClassFields[i].get(desc); 32 | if(o != null && !"".equals(o.toString().trim())){ 33 | srcClassFields[i].setAccessible(true); 34 | srcClassFields[i].set(src, o); 35 | } 36 | } 37 | 38 | return src; 39 | } 40 | } -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/util/DateUtil.java: -------------------------------------------------------------------------------- 1 | package com.sustly.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | /** 7 | * @author liyue 8 | * @date 2019/4/4 11:20 9 | */ 10 | public class DateUtil { 11 | 12 | /** 13 | * 获取当前时间 格式yyyy-MM-dd HH:mm:ss 14 | * @return LocalTime 15 | */ 16 | public static String getLocalTime(){ 17 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); 18 | } 19 | } -------------------------------------------------------------------------------- /blog_api/src/main/java/com/sustly/util/Md5Util.java: -------------------------------------------------------------------------------- 1 | package com.sustly.util; 2 | 3 | import org.apache.shiro.crypto.hash.Md5Hash; 4 | 5 | /** 6 | * @author liyue 7 | * @date 2019/3/19 18:16 8 | */ 9 | public class Md5Util { 10 | public static String encrypt(String data){ 11 | Md5Hash md5Hash = new Md5Hash(data,data,3); 12 | return md5Hash.toString(); 13 | } 14 | } -------------------------------------------------------------------------------- /blog_article_provider/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hub.c.163.com/library/java:latest 2 | VOLUME /tmp 3 | ADD target/blog_server.jar app.jar 4 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /blog_article_provider/src/main/java/com/sustly/BlogArticleProvider.java: -------------------------------------------------------------------------------- 1 | package com.sustly; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | 8 | /** 9 | * @Author: liyue 10 | * @Date: 19-9-4 下午5:35 11 | */ 12 | @SpringBootApplication 13 | @EnableDiscoveryClient 14 | @MapperScan(basePackages = "com.systly.dao") 15 | public class BlogArticleProvider { 16 | public static void main(String[] args) { 17 | SpringApplication.run(BlogArticleProvider.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /blog_article_provider/src/main/java/com/sustly/config/ElasticSearchConfig.java: -------------------------------------------------------------------------------- 1 | package com.sustly.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.apache.http.HttpHost; 5 | import org.elasticsearch.client.RestClient; 6 | import org.elasticsearch.client.RestClientBuilder; 7 | import org.elasticsearch.client.RestHighLevelClient; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.annotation.PostConstruct; 13 | import java.util.ArrayList; 14 | 15 | /** 16 | * @Author: liyue 17 | * @Date: 19-9-12 下午4:27 18 | */ 19 | @Configuration 20 | @Slf4j 21 | public class ElasticSearchConfig { 22 | 23 | private ArrayList hostList; 24 | @Value(value = "${elasticsearch.port}") 25 | private Integer port; 26 | @Value(value = "${elasticsearch.ip}") 27 | private String hosts; 28 | /** 连接超时时间 */ 29 | @Value("${elasticsearch.connectTimeOut}") 30 | private static int connectTimeOut; 31 | /** 连接超时时间 */ 32 | @Value("${elasticsearch.socketTimeOut}") 33 | private static int socketTimeOut; 34 | /** 获取连接的超时时间 */ 35 | @Value("${elasticsearch.connectionRequestTimeOut}") 36 | private int connectionRequestTimeOut; 37 | /** 最大连接数 */ 38 | @Value("${elasticsearch.maxConnectNum}") 39 | private int maxConnectNum; 40 | /** 最大路由连接数 */ 41 | @Value("${elasticsearch.maxConnectPerRoute}") 42 | private int maxConnectPerRoute; 43 | 44 | @PostConstruct 45 | public void init() { 46 | hostList = new ArrayList<>(); 47 | String[] hostStrs = hosts.split(","); 48 | for (String host : hostStrs) { 49 | // 使用的协议 50 | String schema = "http"; 51 | hostList.add(new HttpHost(host, port, schema)); 52 | } 53 | } 54 | 55 | @Bean 56 | public RestHighLevelClient client() { 57 | RestClientBuilder builder = RestClient.builder(hostList.toArray(new HttpHost[0])); 58 | // 异步httpclient连接延时配置 59 | builder.setRequestConfigCallback(requestConfigBuilder -> { 60 | requestConfigBuilder.setConnectTimeout(connectTimeOut); 61 | requestConfigBuilder.setSocketTimeout(socketTimeOut); 62 | requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut); 63 | return requestConfigBuilder; 64 | }); 65 | // 异步httpclient连接数配置 66 | builder.setHttpClientConfigCallback(httpClientBuilder -> { 67 | httpClientBuilder.setMaxConnTotal(maxConnectNum); 68 | httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute); 69 | return httpClientBuilder; 70 | }); 71 | return new RestHighLevelClient(builder); 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /blog_article_provider/src/main/java/com/sustly/dao/ArticleDao.java: -------------------------------------------------------------------------------- 1 | package com.sustly.dao; 2 | 3 | import com.sustly.entry.Blog; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Author: liyue 10 | * @Date: 19-9-4 下午4:24 11 | */ 12 | @Mapper 13 | public interface ArticleDao { 14 | 15 | @Select("select * from blog where id =#{id}") 16 | Blog getBlogById(@Param("id") Integer id); 17 | 18 | @Insert("insert into blog (content, create_time, category, title, create_user, views) values (#{content},#{createTime},#{category},#{title},#{createUser},#{views} )") 19 | @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") 20 | void save(Blog blog); 21 | 22 | @Delete("delete * from blog where id=#{id}") 23 | void deleteById(@Param("id") Integer id); 24 | 25 | @Select("select count(*) from blog") 26 | long count(); 27 | 28 | @Select("select * from blog order by create_time desc limit #{startRow}, #{pageSize}") 29 | List findAllPageByCreateTime(@Param("startRow") Integer startRow, @Param("pageSize") Integer pageSize); 30 | 31 | @Select("select * from blog order by views desc limit #{startRow}, #{pageSize}") 32 | List findAllPageByViews(@Param("startRow") Integer startRow, @Param("pageSize")Integer pageSize); 33 | 34 | @Select("select count(*) from blog where category=#{category}") 35 | long countByCategory(@Param("category") String category); 36 | 37 | @Select("select * from blog where category=#{category} order by create_time desc limit #{startRow}, #{pageSize}") 38 | List findAllPageByCategoryAndCreateTime(@Param("category") String category, @Param("startRow") Integer startRow, @Param("pageSize")int pageSize); 39 | 40 | @Select("select * from blog where create_user=#{username} order by create_time desc limit #{startRow}, #{pageSize}") 41 | List findAllPageByCategoryAndUsername(@Param("username") String username, @Param("startRow") Integer startRow, @Param("pageSize") int pageSize); 42 | 43 | @Update("update blog set title=#{title}, category=#{category}, content=#{content}, views=#{views} where id=#{id}") 44 | void update(Blog blog); 45 | } 46 | -------------------------------------------------------------------------------- /blog_article_provider/src/main/java/com/sustly/dao/BlogImageDao.java: -------------------------------------------------------------------------------- 1 | package com.sustly.dao; 2 | 3 | import com.sustly.entry.BlogImage; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Author: liyue 10 | * @Date: 19-9-4 下午5:07 11 | */ 12 | @Mapper 13 | public interface BlogImageDao { 14 | 15 | @Select("select * from blog_image where blog_id=#{blogId}") 16 | List findByBlogId(@Param("blogId") Integer blogId); 17 | 18 | @Delete("delete * from blog_image where blog_id=#{blogId}") 19 | void deleteAllByBlogId(@Param("blogId") Integer blogId); 20 | 21 | @Insert("insert into blog_image(blog_id, image_url) values (#{blogId}, #{imageUrl})") 22 | void save(BlogImage blogImage); 23 | } 24 | -------------------------------------------------------------------------------- /blog_article_provider/src/main/java/com/sustly/service/ArticleService.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service; 2 | 3 | import com.sustly.entry.Blog; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * ArticleService 9 | * @author admin 10 | */ 11 | public interface ArticleService { 12 | /** 13 | * save 14 | * @param blog blog 15 | */ 16 | void save(Blog blog); 17 | 18 | /** 19 | * findById 20 | * @param id id 21 | * @return Blog 22 | */ 23 | Blog findById(Integer id); 24 | 25 | /** 26 | * delete 27 | * @param id id 28 | */ 29 | void delete(Integer id); 30 | 31 | /** 32 | * getAllCount 33 | * @return long 34 | */ 35 | long getAllCount(); 36 | 37 | /** 38 | * 分页查询 39 | * @param page page 40 | * @return List 41 | */ 42 | List getBlogListByPage(Integer page); 43 | 44 | /** 45 | * 分页查询 46 | * @param page page 47 | * @return List 48 | */ 49 | List getBlogListByView(Integer page); 50 | 51 | /** 52 | * getAllCountByCategory 53 | * @param category category 54 | * @return long 55 | */ 56 | long getAllCountByCategory(String category); 57 | 58 | /** 59 | * getBlogListByCategory 60 | * @param page page 61 | * @param category category 62 | * @return List 63 | */ 64 | List getBlogListByCategory(Integer page, String category); 65 | 66 | /** 67 | * search 68 | * @param search search 69 | * @param page page 70 | * @return List 71 | */ 72 | List search(String search, Integer page); 73 | 74 | /** 75 | * getBlogListByUsernameAndPage 76 | * @param page page 77 | * @param username username 78 | * @return List 79 | */ 80 | List getBlogListByUsernameAndPage(Integer page, String username); 81 | } 82 | -------------------------------------------------------------------------------- /blog_article_provider/src/main/java/com/sustly/service/BlogImageService.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service; 2 | 3 | 4 | import com.sustly.entry.Blog; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author admin 10 | */ 11 | public interface BlogImageService { 12 | 13 | /** 14 | * deleteAllByBlogId 15 | * @param blogId blogId 16 | */ 17 | void deleteAllByBlogId(Integer blogId); 18 | 19 | /** 20 | * saveAllImage 21 | * @param blog blog 22 | */ 23 | void saveAllImage(Blog blog); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /blog_article_provider/src/main/java/com/sustly/service/impl/BlogImageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.sustly.service.impl; 2 | 3 | import com.sustly.dao.BlogImageDao; 4 | import com.sustly.entry.Blog; 5 | import com.sustly.entry.BlogImage; 6 | import com.sustly.service.BlogImageService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import java.io.File; 12 | import java.util.List; 13 | 14 | /** 15 | * @author liyue 16 | * @date 2019/7/5 16:33 17 | */ 18 | @Service 19 | @Transactional(rollbackFor = {Exception.class}) 20 | public class BlogImageServiceImpl implements BlogImageService { 21 | 22 | private final BlogImageDao blogImageDao; 23 | 24 | @Autowired 25 | public BlogImageServiceImpl(BlogImageDao blogImageDao) { 26 | this.blogImageDao = blogImageDao; 27 | } 28 | 29 | @Override 30 | public void deleteAllByBlogId(Integer blogId) { 31 | List blogImages = blogImageDao.findByBlogId(blogId); 32 | for (BlogImage blogImage : blogImages) { 33 | String imageUrl = blogImage.getImageUrl(); 34 | String[] split = imageUrl.split("="); 35 | File file = new File(split[1]); 36 | if (file.exists()){ 37 | file.delete(); 38 | } 39 | } 40 | blogImageDao.deleteAllByBlogId(blogId); 41 | } 42 | 43 | @Override 44 | public void saveAllImage(Blog blog) { 45 | if (blog.getImages() == null){ 46 | return; 47 | } 48 | List images = blog.getImages(); 49 | blogImageDao.deleteAllByBlogId(blog.getId()); 50 | for (String image : images){ 51 | BlogImage blogImage = new BlogImage(); 52 | blogImage.setBlogId(blog.getId()); 53 | blogImage.setImageUrl(image); 54 | blogImageDao.save(blogImage); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /blog_article_provider/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | server.port=8002 2 | 3 | spring.application.name=blog-article-provider 4 | 5 | #mybatis.configuration.map-underscore-to-camel-case=true 6 | # 7 | # 8 | ##Elasticserch 9 | #elasticsearch.port=9200 10 | #elasticsearch.ip=localhost 11 | #elasticsearch.connectTimeOut=1000 12 | #elasticsearch.socketTimeOut=30000 13 | #elasticsearch.connectionRequestTimeOut=500 14 | #elasticsearch.maxConnectNum=100 15 | #elasticsearch.maxConnectPerRoute=100 16 | # 17 | #spring.aop.auto=true 18 | #spring.aop.proxy-target-class=true 19 | # 20 | #spring.datasource.username=root 21 | #spring.datasource.password=123456 22 | #spring.datasource.url=jdbc:mysql://localhost:3306/blog?useSSL=false 23 | #spring.datasource.driver-class-name=com.mysql.jdbc.Driver 24 | #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 25 | 26 | #这里如果使用docker部署,一定要使用分配的内网地址,否则会无法注册 27 | spring.cloud.nacos.discovery.server-addr=localhost:8848 28 | spring.cloud.nacos.config.server-addr=http://localhost:8848 29 | spring.cloud.nacos.config.file-extension=properties 30 | spring.profiles.active=dev 31 | -------------------------------------------------------------------------------- /blog_consumer_feign/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hub.c.163.com/library/java:latest 2 | VOLUME /tmp 3 | ADD target/blog_server.jar app.jar 4 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /blog_consumer_feign/src/main/java/com/sustly/BlogConsumerFeign.java: -------------------------------------------------------------------------------- 1 | package com.sustly; 2 | 3 | import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.openfeign.EnableFeignClients; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.web.client.RestTemplate; 10 | 11 | /** 12 | * @Author: liyue 13 | * @Date: 19-9-4 下午5:48 14 | */ 15 | @SpringBootApplication 16 | @EnableFeignClients(basePackages = {"com.sustly"}) 17 | @EnableDiscoveryClient 18 | public class BlogConsumerFeign { 19 | public static void main(String[] args) { 20 | SpringApplication.run(BlogConsumerFeign.class, args); 21 | } 22 | 23 | @Bean 24 | @SentinelRestTemplate 25 | public RestTemplate getRestTemplate(){ 26 | return new RestTemplate(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /blog_consumer_feign/src/main/java/com/sustly/controller/ConsumerAdminController.java: -------------------------------------------------------------------------------- 1 | package com.sustly.controller; 2 | 3 | import com.sustly.entry.User; 4 | import com.sustly.service.UserClientService; 5 | import com.sustly.dto.ResponseMsg; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | /** 12 | * @Author: liyue 13 | * @Date: 19-9-4 下午5:54 14 | */ 15 | @RestController 16 | public class ConsumerAdminController { 17 | private final UserClientService userService; 18 | 19 | @Autowired 20 | public ConsumerAdminController(UserClientService userService) { 21 | this.userService = userService; 22 | } 23 | 24 | 25 | @PostMapping("/register") 26 | public ResponseMsg register(@RequestBody User user){ 27 | return userService.register(user); 28 | } 29 | 30 | @PostMapping("/login") 31 | public ResponseMsg login(@RequestBody User user){ 32 | return userService.login(user); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /blog_consumer_feign/src/main/java/com/sustly/controller/TestInfoController.java: -------------------------------------------------------------------------------- 1 | package com.sustly.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.cloud.context.config.annotation.RefreshScope; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | /** 9 | * @author liyue 10 | * @date 20-3-26 下午3:10 11 | */ 12 | @RestController 13 | @RefreshScope 14 | public class TestInfoController { 15 | 16 | @Value("${config.info}") 17 | private String info; 18 | 19 | @GetMapping("/getInfo") 20 | public String getInfo(){ 21 | return info; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /blog_consumer_feign/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | server.port=9001 2 | 3 | spring.application.name=blog-consumer-feign 4 | 5 | #feign.sentinel.enabled=true 6 | #spring.cloud.sentinel.transport.dashboard=localhost:7001 7 | # 8 | #ribbon.ConnectTimeout=5000 9 | #ribbon.ReadTimeout=5000 10 | # 11 | #feign.httpclient.connect-timeout=30000 12 | # 13 | # 14 | #ribbon.eager-load.enabled=true 15 | #ribbon.eager-load.clients=blog-consumer-feign 16 | 17 | spring.cloud.nacos.discovery.server-addr=localhost:8848 18 | spring.cloud.nacos.config.server-addr=http://localhost:8848 19 | spring.cloud.nacos.config.file-extension=properties 20 | spring.profiles.active=dev 21 | 22 | -------------------------------------------------------------------------------- /blog_gateway/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hub.c.163.com/library/java:latest 2 | VOLUME /tmp 3 | ADD target/blog_server.jar app.jar 4 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /blog_gateway/src/main/java/com/sustly/Gateway.java: -------------------------------------------------------------------------------- 1 | package com.sustly; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | public class Gateway { 10 | public static void main(String[] args) { 11 | SpringApplication.run(Gateway.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /blog_gateway/src/main/java/com/sustly/filter/LogsFilter.java: -------------------------------------------------------------------------------- 1 | package com.sustly.filter; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.cloud.gateway.filter.GatewayFilterChain; 5 | import org.springframework.cloud.gateway.filter.GlobalFilter; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.Ordered; 8 | import org.springframework.http.server.reactive.ServerHttpRequest; 9 | import org.springframework.web.server.ServerWebExchange; 10 | import reactor.core.publisher.Mono; 11 | 12 | /** 13 | * @author liyue 14 | * @date 20-3-17 下午4:28 15 | */ 16 | @Configuration 17 | @Slf4j 18 | public class LogsFilter implements GlobalFilter, Ordered { 19 | 20 | @Override 21 | public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { 22 | ServerHttpRequest request = exchange.getRequest(); 23 | log.info("path: " + request.getPath()); 24 | log.info("address: " + request.getRemoteAddress()); 25 | log.info("method: " + request.getMethodValue()); 26 | log.info("URI: " + request.getURI()); 27 | log.info("Headers: " + request.getHeaders()); 28 | Object requestBody = exchange.getAttribute("cachedRequestBodyObject"); 29 | log.info("body: "+ requestBody); 30 | return chain.filter(exchange); 31 | } 32 | 33 | @Override 34 | public int getOrder() { 35 | return Ordered.HIGHEST_PRECEDENCE; 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /blog_gateway/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | server.port=9527 2 | 3 | spring.application.name=blog_gateway 4 | 5 | 6 | spring.cloud.nacos.discovery.server-addr=localhost:8848 7 | 8 | #spring.cloud.gateway.discovery.locator.enabled=true 9 | #spring.cloud.gateway.routes[0].id=blog-consumer-feign 10 | #spring.cloud.gateway.routes[0].uri=lb://blog-consumer-feign 11 | #spring.cloud.gateway.routes[0].predicates[0]=Path=/blog/** 12 | ##去掉blog在转发 13 | #spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1 14 | 15 | spring.cloud.nacos.config.server-addr=http://localhost:8848 16 | spring.cloud.nacos.config.file-extension=properties 17 | spring.profiles.active=dev 18 | 19 | -------------------------------------------------------------------------------- /sentinel-dashboard/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hub.c.163.com/library/java:latest 2 | VOLUME /tmp 3 | ADD target/sentinel-dashboard.jar app.jar 4 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /sentinel-dashboard/README.md: -------------------------------------------------------------------------------- 1 | # Sentinel 控制台 2 | 3 | ## 0. 概述 4 | 5 | Sentinel 控制台是流量控制、熔断降级规则统一配置和管理的入口,它为用户提供了机器自发现、簇点链路自发现、监控、规则配置等功能。在 Sentinel 控制台上,我们可以配置规则并实时查看流量控制效果。 6 | 7 | ## 1. 编译和启动 8 | 9 | ### 1.1 如何编译 10 | 11 | 使用如下命令将代码打包成一个 fat jar: 12 | 13 | ```bash 14 | mvn clean package 15 | ``` 16 | 17 | ### 1.2 如何启动 18 | 19 | 使用如下命令启动编译后的控制台: 20 | 21 | ```bash 22 | java -Dserver.port=8080 \ 23 | -Dcsp.sentinel.dashboard.server=localhost:8080 \ 24 | -Dproject.name=sentinel-dashboard \ 25 | -jar target/sentinel-dashboard.jar 26 | ``` 27 | 28 | 上述命令中我们指定几个 JVM 参数,其中 `-Dserver.port=8080` 是 Spring Boot 的参数, 29 | 用于指定 Spring Boot 服务端启动端口为 `8080`。其余几个是 Sentinel 客户端的参数。 30 | 31 | 为便于演示,我们对控制台本身加入了流量控制功能,具体做法是引入 Sentinel 提供的 `CommonFilter` 这个 Servlet Filter。 32 | 上述 JVM 参数的含义是: 33 | 34 | | 参数 | 作用 | 35 | |--------|--------| 36 | |`Dcsp.sentinel.dashboard.server=localhost:8080`|向 Sentinel 接入端指定控制台的地址| 37 | |`-Dproject.name=sentinel-dashboard`|向 Sentinel 指定应用名称,比如上面对应的应用名称就为 `sentinel-dashboard`| 38 | 39 | 全部的配置项可以参考 [启动配置项文档](https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9)。 40 | 41 | 经过上述配置,控制台启动后会自动向自己发送心跳。程序启动后浏览器访问 `localhost:8080` 即可访问 Sentinel 控制台。 42 | 43 | 从 Sentinel 1.6.0 开始,Sentinel 控制台支持简单的**登录**功能,默认用户名和密码都是 `sentinel`。用户可以通过如下参数进行配置: 44 | 45 | - `-Dsentinel.dashboard.auth.username=sentinel` 用于指定控制台的登录用户名为 `sentinel`; 46 | - `-Dsentinel.dashboard.auth.password=123456` 用于指定控制台的登录密码为 `123456`;如果省略这两个参数,默认用户和密码均为 `sentinel`; 47 | - `-Dserver.servlet.session.timeout=7200` 用于指定 Spring Boot 服务端 session 的过期时间,如 `7200` 表示 7200 秒;`60m` 表示 60 分钟,默认为 30 分钟; 48 | 49 | ## 2. 客户端接入 50 | 51 | 选择合适的方式接入 Sentinel,然后在应用启动时加入 JVM 参数 `-Dcsp.sentinel.dashboard.server=consoleIp:port` 指定控制台地址和端口。 52 | 确保客户端有访问量,**Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包**,将客户端纳入到控制台的管辖之下。 53 | 54 | 客户端接入的详细步骤请参考 [Wiki 文档](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0#3-%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%8E%A5%E5%85%A5%E6%8E%A7%E5%88%B6%E5%8F%B0)。 55 | 56 | ## 3. 验证是否接入成功 57 | 58 | 客户端正确配置并启动后,会**在初次调用后**主动向控制台发送心跳包,汇报自己的存在; 59 | 控制台收到客户端心跳包之后,会在左侧导航栏中显示该客户端信息。如果控制台能够看到客户端的机器信息,则表明客户端接入成功了。 60 | 61 | 更多:[控制台功能介绍](./Sentinel_Dashboard_Feature.md)。 -------------------------------------------------------------------------------- /sentinel-dashboard/Sentinel_Dashboard_Feature.md: -------------------------------------------------------------------------------- 1 | # Sentinel 控制台功能介绍 2 | 3 | ## 0. 概述 4 | 5 | Sentinel 控制台是流量控制、熔断降级规则统一配置和管理的入口,它为用户提供了机器自发现、簇点链路自发现、监控、规则配置等功能。在 Sentinel 控制台上,我们可以配置规则并实时查看流量控制效果。使用 Sentinel 控制台的流程如下: 6 | 7 | ``` 8 | 客户端接入 -> 机器自发现 -> 查看簇点链路 -> 配置流控规则 -> 查看流控效果 9 | ``` 10 | 11 | ## 1. 功能介绍 12 | 13 | ### 1.1 机器自发现 14 | 15 | Sentinel 提供内置的机器自发现功能,无需依赖第三方服务发现组件即可实现客户端的发现。点击 Sentinel 控制台左侧导航栏的“机器列表”菜单,可查看集群机器数量和机器健康状况。 16 | 17 | ### 1.2 簇点链路自发现 18 | 19 | Sentinel 将每一个需要流控的 URL 或者接口称为一个资源,并使用URL地址或方法签名表示资源。Sentinel 会自动发现所有潜在的资源和资源之间的调用链,并在“簇点链路”页面展示。 20 | 资源是设置流控规则的载体,通过簇点链路自发现,可以方便的对重要资源设置流控规则、熔断降级规则等。 21 | 22 | > 注意:**客户端有访问量之后,才能在簇点链路页面看到资源监控(lazy-initializing)**。 23 | 24 | ### 1.3 实时监控 25 | 26 | Sentinel 监控功能能够实时查看集群中每个资源的实时访问以及流控情况。控制台左侧导航栏的“实时监控”菜单对应该功能。 27 | 28 | ### 1.4 流控降级规则设置 29 | 30 | Sentinel 提供了多种规则来保护系统的不同部分。流量控制规则用于保护服务提供方,熔断降级规则用于保护服务消费方,系统保护规则用于保护整个系统。 31 | 32 | #### 1.4.1 流量控制规则 33 | 34 | 流量控制规则用于保护服务提供方,服务提供方指任何可以对外提供服务的系统,比如向终端用户提供 Web 服务的 Web 应用,向微服务消费方提供服务的 Dubbo Service Provider 等。 35 | 系统的服务能力是有限的,如果消费方请求速度过高,则采用相应的保护策略,或是直接拒绝,或是排队等待。通过“流控规则”页面可以查看和配置流量控制规则。 36 | 37 | #### 1.4.2 熔断降级规则 38 | 39 | 降级规则用于保护服务消费方。在微服务架构中,业务系统通常要依赖多个服务,依赖的某个服务不可用将会影响业务系统的可用性。解决这个问题的方法是及时发现服务的“不可用”状态,在调用时快速失败而不是等待调动超时或者重试。Sentinel 通过熔断降级来达到快速失败的目的。通过“降级规则”页面可以查看和配置降级规则。 40 | 41 | #### 1.4.3 系统保护规则 42 | 43 | 系统保护规则(简称`系统规则`)用于保护整个系统指标处于安全水位。无论是服务提供方还是消费方,活跃线程数过多、系统LOAD等过高都是系统处于高水位的指标。当系统水位过高时,系统应拒绝对外提供服务以便迅速降低资源占用。通过“系统规则”页面可以查看和设置系统保护规则。 44 | 45 | ## 2. 限制 46 | 47 | 本控制台只是用于演示 Sentinel 的基本能力和工作流程,并没有依赖生产环境中所必需的组件,比如**持久化的后端数据库、可靠的配置中心**等。 48 | 目前 Sentinel 采用内存态的方式存储监控和规则数据,监控最长存储时间为 5 分钟,控制台重启后数据丢失。 49 | 50 | ## 3. 配置项 51 | 52 | 控制台的一些特性可以通过配置项来进行配置,配置项主要有两个来源:`System.getProperty()` 和 `System.getenv()`,同时存在时后者可以覆盖前者。 53 | 54 | > 通过环境变量进行配置时,因为不支持 `.` 所以需要将其更换为 `_`。 55 | 56 | 项 | 类型 | 默认值 | 最小值 | 描述 57 | --- | --- | --- | --- | --- 58 | sentinel.dashboard.auth.username | String | sentinel | 无 | 登录控制台的用户名,默认为 `sentinel` 59 | sentinel.dashboard.auth.password | String | sentinel | 无 | 登录控制台的密码,默认为 `sentinel` 60 | sentinel.dashboard.app.hideAppNoMachineMillis | Integer | 0 | 60000 | 是否隐藏无健康节点的应用,距离最近一次主机心跳时间的毫秒数,默认关闭 61 | sentinel.dashboard.removeAppNoMachineMillis | Integer | 0 | 120000 | 是否自动删除无健康节点的应用,距离最近一次其下节点的心跳时间毫秒数,默认关闭 62 | sentinel.dashboard.unhealthyMachineMillis | Integer | 60000 | 30000 | 主机失联判定,不可关闭 63 | sentinel.dashboard.autoRemoveMachineMillis | Integer | 0 | 300000 | 距离最近心跳时间超过指定时间是否自动删除失联节点,默认关闭 64 | 65 | 配置示例: 66 | 67 | - 命令行方式: 68 | 69 | ```shell 70 | java -Dsentinel.dashboard.app.hideAppNoMachineMillis=60000 71 | ``` 72 | 73 | - Java 方式: 74 | 75 | ```java 76 | System.setProperty("sentinel.dashboard.app.hideAppNoMachineMillis", "60000"); 77 | ``` 78 | 79 | - 环境变量方式: 80 | 81 | ```shell 82 | sentinel_dashboard_app_hideAppNoMachineMillis=60000 83 | ``` 84 | 85 | 更多: 86 | 87 | - [Sentinel 控制台启动和客户端接入](./README.md) 88 | - [控制台 Wiki](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0) -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/DashboardApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard; 17 | 18 | import com.alibaba.csp.sentinel.init.InitExecutor; 19 | 20 | import org.springframework.boot.SpringApplication; 21 | import org.springframework.boot.autoconfigure.SpringBootApplication; 22 | 23 | /** 24 | * Sentinel dashboard application. 25 | * 26 | * @author Carpenter Lee 27 | */ 28 | @SpringBootApplication 29 | public class DashboardApplication { 30 | 31 | public static void main(String[] args) { 32 | triggerSentinelInit(); 33 | SpringApplication.run(DashboardApplication.class, args); 34 | } 35 | 36 | private static void triggerSentinelInit() { 37 | new Thread(() -> InitExecutor.doInit()).start(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/FakeAuthServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.auth; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | 20 | import org.springframework.stereotype.Component; 21 | 22 | /** 23 | * A fake AuthService implementation, which will pass all user auth checking. 24 | * 25 | * @author Carpenter Lee 26 | * @since 1.5.0 27 | */ 28 | @Component 29 | public class FakeAuthServiceImpl implements AuthService { 30 | 31 | @Override 32 | public AuthUser getAuthUser(HttpServletRequest request) { 33 | return new AuthUserImpl(); 34 | } 35 | 36 | static final class AuthUserImpl implements AuthUser { 37 | 38 | @Override 39 | public boolean authTarget(String target, PrivilegeType privilegeType) { 40 | // fake implementation, always return true 41 | return true; 42 | } 43 | 44 | @Override 45 | public boolean isSuperUser() { 46 | // fake implementation, always return true 47 | return true; 48 | } 49 | 50 | @Override 51 | public String getNickName() { 52 | return "FAKE_NICK_NAME"; 53 | } 54 | 55 | @Override 56 | public String getLoginName() { 57 | return "FAKE_LOGIN_NAME"; 58 | } 59 | 60 | @Override 61 | public String getId() { 62 | return "FAKE_EMP_ID"; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/SimpleWebAuthServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.auth; 17 | 18 | import org.springframework.context.annotation.Primary; 19 | import org.springframework.stereotype.Component; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | import javax.servlet.http.HttpSession; 23 | 24 | /** 25 | * @author cdfive 26 | * @since 1.6.0 27 | */ 28 | @Primary 29 | @Component 30 | public class SimpleWebAuthServiceImpl implements AuthService { 31 | 32 | public static final String WEB_SESSTION_KEY = "session_sentinel_admin"; 33 | 34 | @Override 35 | public AuthUser getAuthUser(HttpServletRequest request) { 36 | HttpSession session = request.getSession(); 37 | Object sentinelUserObj = session.getAttribute(SimpleWebAuthServiceImpl.WEB_SESSTION_KEY); 38 | if (sentinelUserObj != null && sentinelUserObj instanceof AuthUser) { 39 | return (AuthUser) sentinelUserObj; 40 | } 41 | 42 | return null; 43 | } 44 | 45 | public static final class SimpleWebAuthUserImpl implements AuthUser { 46 | 47 | private String username; 48 | 49 | public SimpleWebAuthUserImpl(String username) { 50 | this.username = username; 51 | } 52 | 53 | @Override 54 | public boolean authTarget(String target, PrivilegeType privilegeType) { 55 | return true; 56 | } 57 | 58 | @Override 59 | public boolean isSuperUser() { 60 | return true; 61 | } 62 | 63 | @Override 64 | public String getNickName() { 65 | return username; 66 | } 67 | 68 | @Override 69 | public String getLoginName() { 70 | return username; 71 | } 72 | 73 | @Override 74 | public String getId() { 75 | return username; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/CommandFailedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.client; 17 | 18 | /** 19 | * @author Eric Zhao 20 | */ 21 | public class CommandFailedException extends RuntimeException { 22 | 23 | public CommandFailedException() {} 24 | 25 | public CommandFailedException(String message) { 26 | super(message); 27 | } 28 | 29 | @Override 30 | public synchronized Throwable fillInStackTrace() { 31 | return this; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/CommandNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.client; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 0.2.1 21 | */ 22 | public class CommandNotFoundException extends Exception { 23 | 24 | public CommandNotFoundException() { } 25 | 26 | public CommandNotFoundException(String message) { 27 | super(message); 28 | } 29 | 30 | @Override 31 | public synchronized Throwable fillInStackTrace() { 32 | return this; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/ApplicationEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.datasource.entity; 17 | 18 | import java.util.Date; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.discovery.AppInfo; 21 | 22 | /** 23 | * @author leyou 24 | */ 25 | public class ApplicationEntity { 26 | 27 | private Long id; 28 | private Date gmtCreate; 29 | private Date gmtModified; 30 | private String app; 31 | private Integer appType; 32 | private String activeConsole; 33 | private Date lastFetch; 34 | 35 | public long getId() { 36 | return id; 37 | } 38 | 39 | public void setId(long id) { 40 | this.id = id; 41 | } 42 | 43 | public Date getGmtCreate() { 44 | return gmtCreate; 45 | } 46 | 47 | public void setGmtCreate(Date gmtCreate) { 48 | this.gmtCreate = gmtCreate; 49 | } 50 | 51 | public Date getGmtModified() { 52 | return gmtModified; 53 | } 54 | 55 | public void setGmtModified(Date gmtModified) { 56 | this.gmtModified = gmtModified; 57 | } 58 | 59 | public String getApp() { 60 | return app; 61 | } 62 | 63 | public void setApp(String app) { 64 | this.app = app; 65 | } 66 | 67 | public Integer getAppType() { 68 | return appType; 69 | } 70 | 71 | public void setAppType(Integer appType) { 72 | this.appType = appType; 73 | } 74 | 75 | public String getActiveConsole() { 76 | return activeConsole; 77 | } 78 | 79 | public Date getLastFetch() { 80 | return lastFetch; 81 | } 82 | 83 | public void setLastFetch(Date lastFetch) { 84 | this.lastFetch = lastFetch; 85 | } 86 | 87 | public void setActiveConsole(String activeConsole) { 88 | this.activeConsole = activeConsole; 89 | } 90 | 91 | public AppInfo toAppInfo() { 92 | return new AppInfo(app, appType); 93 | } 94 | 95 | @Override 96 | public String toString() { 97 | return "ApplicationEntity{" + 98 | "id=" + id + 99 | ", gmtCreate=" + gmtCreate + 100 | ", gmtModified=" + gmtModified + 101 | ", app='" + app + '\'' + 102 | ", activeConsole='" + activeConsole + '\'' + 103 | ", lastFetch=" + lastFetch + 104 | '}'; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/gateway/ApiPredicateItemEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway; 17 | 18 | import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem; 19 | 20 | import java.util.Objects; 21 | 22 | /** 23 | * Entity for {@link ApiPredicateItem}. 24 | * 25 | * @author cdfive 26 | * @since 1.7.0 27 | */ 28 | public class ApiPredicateItemEntity { 29 | 30 | private String pattern; 31 | 32 | private Integer matchStrategy; 33 | 34 | public ApiPredicateItemEntity() { 35 | } 36 | 37 | public ApiPredicateItemEntity(String pattern, int matchStrategy) { 38 | this.pattern = pattern; 39 | this.matchStrategy = matchStrategy; 40 | } 41 | 42 | public String getPattern() { 43 | return pattern; 44 | } 45 | 46 | public void setPattern(String pattern) { 47 | this.pattern = pattern; 48 | } 49 | 50 | public Integer getMatchStrategy() { 51 | return matchStrategy; 52 | } 53 | 54 | public void setMatchStrategy(Integer matchStrategy) { 55 | this.matchStrategy = matchStrategy; 56 | } 57 | 58 | @Override 59 | public boolean equals(Object o) { 60 | if (this == o) { return true; } 61 | if (o == null || getClass() != o.getClass()) { return false; } 62 | ApiPredicateItemEntity that = (ApiPredicateItemEntity) o; 63 | return Objects.equals(pattern, that.pattern) && 64 | Objects.equals(matchStrategy, that.matchStrategy); 65 | } 66 | 67 | @Override 68 | public int hashCode() { 69 | return Objects.hash(pattern, matchStrategy); 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return "ApiPredicateItemEntity{" + 75 | "pattern='" + pattern + '\'' + 76 | ", matchStrategy=" + matchStrategy + 77 | '}'; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/AbstractRuleEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule; 17 | 18 | import java.util.Date; 19 | 20 | import com.alibaba.csp.sentinel.slots.block.AbstractRule; 21 | import com.alibaba.csp.sentinel.slots.block.Rule; 22 | 23 | /** 24 | * @author Eric Zhao 25 | * @since 0.2.1 26 | */ 27 | public abstract class AbstractRuleEntity implements RuleEntity { 28 | 29 | protected Long id; 30 | 31 | protected String app; 32 | protected String ip; 33 | protected Integer port; 34 | 35 | protected T rule; 36 | 37 | private Date gmtCreate; 38 | private Date gmtModified; 39 | 40 | @Override 41 | public Long getId() { 42 | return id; 43 | } 44 | 45 | @Override 46 | public void setId(Long id) { 47 | this.id = id; 48 | } 49 | 50 | @Override 51 | public String getApp() { 52 | return app; 53 | } 54 | 55 | public AbstractRuleEntity setApp(String app) { 56 | this.app = app; 57 | return this; 58 | } 59 | 60 | @Override 61 | public String getIp() { 62 | return ip; 63 | } 64 | 65 | public AbstractRuleEntity setIp(String ip) { 66 | this.ip = ip; 67 | return this; 68 | } 69 | 70 | @Override 71 | public Integer getPort() { 72 | return port; 73 | } 74 | 75 | public AbstractRuleEntity setPort(Integer port) { 76 | this.port = port; 77 | return this; 78 | } 79 | 80 | public T getRule() { 81 | return rule; 82 | } 83 | 84 | public AbstractRuleEntity setRule(T rule) { 85 | this.rule = rule; 86 | return this; 87 | } 88 | 89 | @Override 90 | public Date getGmtCreate() { 91 | return gmtCreate; 92 | } 93 | 94 | public AbstractRuleEntity setGmtCreate(Date gmtCreate) { 95 | this.gmtCreate = gmtCreate; 96 | return this; 97 | } 98 | 99 | public Date getGmtModified() { 100 | return gmtModified; 101 | } 102 | 103 | public AbstractRuleEntity setGmtModified(Date gmtModified) { 104 | this.gmtModified = gmtModified; 105 | return this; 106 | } 107 | 108 | @Override 109 | public T toRule() { 110 | return rule; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule; 17 | 18 | import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule; 19 | import com.alibaba.csp.sentinel.util.AssertUtil; 20 | 21 | import com.fasterxml.jackson.annotation.JsonIgnore; 22 | 23 | /** 24 | * @author Eric Zhao 25 | * @since 0.2.1 26 | */ 27 | public class AuthorityRuleEntity extends AbstractRuleEntity { 28 | 29 | public AuthorityRuleEntity() {} 30 | 31 | public AuthorityRuleEntity(AuthorityRule authorityRule) { 32 | AssertUtil.notNull(authorityRule, "Authority rule should not be null"); 33 | this.rule = authorityRule; 34 | } 35 | 36 | public static AuthorityRuleEntity fromAuthorityRule(String app, String ip, Integer port, AuthorityRule rule) { 37 | AuthorityRuleEntity entity = new AuthorityRuleEntity(rule); 38 | entity.setApp(app); 39 | entity.setIp(ip); 40 | entity.setPort(port); 41 | return entity; 42 | } 43 | 44 | @JsonIgnore 45 | public String getLimitApp() { 46 | return rule.getLimitApp(); 47 | } 48 | 49 | @JsonIgnore 50 | public String getResource() { 51 | return rule.getResource(); 52 | } 53 | 54 | @JsonIgnore 55 | public int getStrategy() { 56 | return rule.getStrategy(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/RuleEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule; 17 | 18 | import java.util.Date; 19 | 20 | import com.alibaba.csp.sentinel.slots.block.Rule; 21 | 22 | /** 23 | * @author leyou 24 | */ 25 | public interface RuleEntity { 26 | 27 | Long getId(); 28 | 29 | void setId(Long id); 30 | 31 | String getApp(); 32 | 33 | String getIp(); 34 | 35 | Integer getPort(); 36 | 37 | Date getGmtCreate(); 38 | 39 | Rule toRule(); 40 | } 41 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppManagement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.discovery; 17 | 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | import javax.annotation.PostConstruct; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.context.ApplicationContext; 25 | import org.springframework.stereotype.Component; 26 | 27 | @Component 28 | public class AppManagement implements MachineDiscovery { 29 | 30 | @Autowired 31 | private ApplicationContext context; 32 | 33 | private MachineDiscovery machineDiscovery; 34 | 35 | @PostConstruct 36 | public void init() { 37 | machineDiscovery = context.getBean(SimpleMachineDiscovery.class); 38 | } 39 | 40 | @Override 41 | public Set getBriefApps() { 42 | return machineDiscovery.getBriefApps(); 43 | } 44 | 45 | @Override 46 | public long addMachine(MachineInfo machineInfo) { 47 | return machineDiscovery.addMachine(machineInfo); 48 | } 49 | 50 | @Override 51 | public boolean removeMachine(String app, String ip, int port) { 52 | return machineDiscovery.removeMachine(app, ip, port); 53 | } 54 | 55 | @Override 56 | public List getAppNames() { 57 | return machineDiscovery.getAppNames(); 58 | } 59 | 60 | @Override 61 | public AppInfo getDetailApp(String app) { 62 | return machineDiscovery.getDetailApp(app); 63 | } 64 | 65 | @Override 66 | public void removeApp(String app) { 67 | machineDiscovery.removeApp(app); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/MachineDiscovery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.discovery; 17 | 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | public interface MachineDiscovery { 22 | 23 | String UNKNOWN_APP_NAME = "CLUSTER_NOT_STARTED"; 24 | 25 | List getAppNames(); 26 | 27 | Set getBriefApps(); 28 | 29 | AppInfo getDetailApp(String app); 30 | 31 | /** 32 | * Remove the given app from the application registry. 33 | * 34 | * @param app application name 35 | * @since 1.5.0 36 | */ 37 | void removeApp(String app); 38 | 39 | long addMachine(MachineInfo machineInfo); 40 | 41 | /** 42 | * Remove the given machine instance from the application registry. 43 | * 44 | * @param app the application name of the machine 45 | * @param ip machine IP 46 | * @param port machine port 47 | * @return true if removed, otherwise false 48 | * @since 1.5.0 49 | */ 50 | boolean removeMachine(String app, String ip, int port); 51 | } -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/SimpleMachineDiscovery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.discovery; 17 | 18 | import java.util.ArrayList; 19 | import java.util.HashSet; 20 | import java.util.List; 21 | import java.util.Set; 22 | import java.util.concurrent.ConcurrentHashMap; 23 | import java.util.concurrent.ConcurrentMap; 24 | 25 | import com.alibaba.csp.sentinel.util.AssertUtil; 26 | 27 | import org.springframework.stereotype.Component; 28 | 29 | /** 30 | * @author leyou 31 | */ 32 | @Component 33 | public class SimpleMachineDiscovery implements MachineDiscovery { 34 | 35 | private final ConcurrentMap apps = new ConcurrentHashMap<>(); 36 | 37 | @Override 38 | public long addMachine(MachineInfo machineInfo) { 39 | AssertUtil.notNull(machineInfo, "machineInfo cannot be null"); 40 | AppInfo appInfo = apps.computeIfAbsent(machineInfo.getApp(), o -> new AppInfo(machineInfo.getApp(), machineInfo.getAppType())); 41 | appInfo.addMachine(machineInfo); 42 | return 1; 43 | } 44 | 45 | @Override 46 | public boolean removeMachine(String app, String ip, int port) { 47 | AssertUtil.assertNotBlank(app, "app name cannot be blank"); 48 | AppInfo appInfo = apps.get(app); 49 | if (appInfo != null) { 50 | return appInfo.removeMachine(ip, port); 51 | } 52 | return false; 53 | } 54 | 55 | @Override 56 | public List getAppNames() { 57 | return new ArrayList<>(apps.keySet()); 58 | } 59 | 60 | @Override 61 | public AppInfo getDetailApp(String app) { 62 | AssertUtil.assertNotBlank(app, "app name cannot be blank"); 63 | return apps.get(app); 64 | } 65 | 66 | @Override 67 | public Set getBriefApps() { 68 | return new HashSet<>(apps.values()); 69 | } 70 | 71 | @Override 72 | public void removeApp(String app) { 73 | AssertUtil.assertNotBlank(app, "app name cannot be blank"); 74 | apps.remove(app); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/Result.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain; 17 | 18 | /** 19 | * @author leyou 20 | * @author Eric Zhao 21 | */ 22 | public class Result { 23 | 24 | private boolean success; 25 | private int code; 26 | private String msg; 27 | private R data; 28 | 29 | public static Result ofSuccess(R data) { 30 | return new Result() 31 | .setSuccess(true) 32 | .setMsg("success") 33 | .setData(data); 34 | } 35 | 36 | public static Result ofSuccessMsg(String msg) { 37 | return new Result() 38 | .setSuccess(true) 39 | .setMsg(msg); 40 | } 41 | 42 | public static Result ofFail(int code, String msg) { 43 | Result result = new Result<>(); 44 | result.setSuccess(false); 45 | result.setCode(code); 46 | result.setMsg(msg); 47 | return result; 48 | } 49 | 50 | public static Result ofThrowable(int code, Throwable throwable) { 51 | Result result = new Result<>(); 52 | result.setSuccess(false); 53 | result.setCode(code); 54 | result.setMsg(throwable.getClass().getName() + ", " + throwable.getMessage()); 55 | return result; 56 | } 57 | 58 | public boolean isSuccess() { 59 | return success; 60 | } 61 | 62 | public Result setSuccess(boolean success) { 63 | this.success = success; 64 | return this; 65 | } 66 | 67 | public int getCode() { 68 | return code; 69 | } 70 | 71 | public Result setCode(int code) { 72 | this.code = code; 73 | return this; 74 | } 75 | 76 | public String getMsg() { 77 | return msg; 78 | } 79 | 80 | public Result setMsg(String msg) { 81 | this.msg = msg; 82 | return this; 83 | } 84 | 85 | public R getData() { 86 | return data; 87 | } 88 | 89 | public Result setData(R data) { 90 | this.data = data; 91 | return this; 92 | } 93 | 94 | @Override 95 | public String toString() { 96 | return "Result{" + 97 | "success=" + success + 98 | ", code=" + code + 99 | ", msg='" + msg + '\'' + 100 | ", data=" + data + 101 | '}'; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ClusterAppAssignResultVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | import java.util.Set; 19 | 20 | /** 21 | * @author Eric Zhao 22 | * @since 1.4.1 23 | */ 24 | public class ClusterAppAssignResultVO { 25 | 26 | private Set failedServerSet; 27 | private Set failedClientSet; 28 | 29 | private Integer totalCount; 30 | 31 | public Set getFailedServerSet() { 32 | return failedServerSet; 33 | } 34 | 35 | public ClusterAppAssignResultVO setFailedServerSet(Set failedServerSet) { 36 | this.failedServerSet = failedServerSet; 37 | return this; 38 | } 39 | 40 | public Set getFailedClientSet() { 41 | return failedClientSet; 42 | } 43 | 44 | public ClusterAppAssignResultVO setFailedClientSet(Set failedClientSet) { 45 | this.failedClientSet = failedClientSet; 46 | return this; 47 | } 48 | 49 | public Integer getTotalCount() { 50 | return totalCount; 51 | } 52 | 53 | public ClusterAppAssignResultVO setTotalCount(Integer totalCount) { 54 | this.totalCount = totalCount; 55 | return this; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "ClusterAppAssignResultVO{" + 61 | "failedServerSet=" + failedServerSet + 62 | ", failedClientSet=" + failedClientSet + 63 | ", totalCount=" + totalCount + 64 | '}'; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ClusterAppFullAssignRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | import com.alibaba.csp.sentinel.dashboard.domain.cluster.request.ClusterAppAssignMap; 22 | 23 | /** 24 | * @author Eric Zhao 25 | * @since 1.4.1 26 | */ 27 | public class ClusterAppFullAssignRequest { 28 | 29 | private List clusterMap; 30 | private Set remainingList; 31 | 32 | public List getClusterMap() { 33 | return clusterMap; 34 | } 35 | 36 | public ClusterAppFullAssignRequest setClusterMap( 37 | List clusterMap) { 38 | this.clusterMap = clusterMap; 39 | return this; 40 | } 41 | 42 | public Set getRemainingList() { 43 | return remainingList; 44 | } 45 | 46 | public ClusterAppFullAssignRequest setRemainingList(Set remainingList) { 47 | this.remainingList = remainingList; 48 | return this; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "ClusterAppFullAssignRequest{" + 54 | "clusterMap=" + clusterMap + 55 | ", remainingList=" + remainingList + 56 | '}'; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ClusterAppSingleServerAssignRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | import java.util.Set; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.domain.cluster.request.ClusterAppAssignMap; 21 | 22 | /** 23 | * @author Eric Zhao 24 | * @since 1.4.1 25 | */ 26 | public class ClusterAppSingleServerAssignRequest { 27 | 28 | private ClusterAppAssignMap clusterMap; 29 | private Set remainingList; 30 | 31 | public ClusterAppAssignMap getClusterMap() { 32 | return clusterMap; 33 | } 34 | 35 | public ClusterAppSingleServerAssignRequest setClusterMap(ClusterAppAssignMap clusterMap) { 36 | this.clusterMap = clusterMap; 37 | return this; 38 | } 39 | 40 | public Set getRemainingList() { 41 | return remainingList; 42 | } 43 | 44 | public ClusterAppSingleServerAssignRequest setRemainingList(Set remainingList) { 45 | this.remainingList = remainingList; 46 | return this; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "ClusterAppSingleServerAssignRequest{" + 52 | "clusterMap=" + clusterMap + 53 | ", remainingList=" + remainingList + 54 | '}'; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ClusterClientInfoVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.1 21 | */ 22 | public class ClusterClientInfoVO { 23 | 24 | private String serverHost; 25 | private Integer serverPort; 26 | 27 | private Integer clientState; 28 | 29 | private Integer requestTimeout; 30 | 31 | public String getServerHost() { 32 | return serverHost; 33 | } 34 | 35 | public ClusterClientInfoVO setServerHost(String serverHost) { 36 | this.serverHost = serverHost; 37 | return this; 38 | } 39 | 40 | public Integer getServerPort() { 41 | return serverPort; 42 | } 43 | 44 | public ClusterClientInfoVO setServerPort(Integer serverPort) { 45 | this.serverPort = serverPort; 46 | return this; 47 | } 48 | 49 | public Integer getClientState() { 50 | return clientState; 51 | } 52 | 53 | public ClusterClientInfoVO setClientState(Integer clientState) { 54 | this.clientState = clientState; 55 | return this; 56 | } 57 | 58 | public Integer getRequestTimeout() { 59 | return requestTimeout; 60 | } 61 | 62 | public ClusterClientInfoVO setRequestTimeout(Integer requestTimeout) { 63 | this.requestTimeout = requestTimeout; 64 | return this; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return "ClusterClientInfoVO{" + 70 | "serverHost='" + serverHost + '\'' + 71 | ", serverPort=" + serverPort + 72 | ", clientState=" + clientState + 73 | ", requestTimeout=" + requestTimeout + 74 | '}'; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ClusterGroupEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | /** 22 | * @author Eric Zhao 23 | * @since 1.4.1 24 | */ 25 | public class ClusterGroupEntity { 26 | 27 | private String machineId; 28 | 29 | private String ip; 30 | private Integer port; 31 | 32 | private Set clientSet = new HashSet<>(); 33 | 34 | private Boolean belongToApp; 35 | 36 | public String getMachineId() { 37 | return machineId; 38 | } 39 | 40 | public ClusterGroupEntity setMachineId(String machineId) { 41 | this.machineId = machineId; 42 | return this; 43 | } 44 | 45 | public String getIp() { 46 | return ip; 47 | } 48 | 49 | public ClusterGroupEntity setIp(String ip) { 50 | this.ip = ip; 51 | return this; 52 | } 53 | 54 | public Integer getPort() { 55 | return port; 56 | } 57 | 58 | public ClusterGroupEntity setPort(Integer port) { 59 | this.port = port; 60 | return this; 61 | } 62 | 63 | public Set getClientSet() { 64 | return clientSet; 65 | } 66 | 67 | public ClusterGroupEntity setClientSet(Set clientSet) { 68 | this.clientSet = clientSet; 69 | return this; 70 | } 71 | 72 | public Boolean getBelongToApp() { 73 | return belongToApp; 74 | } 75 | 76 | public ClusterGroupEntity setBelongToApp(Boolean belongToApp) { 77 | this.belongToApp = belongToApp; 78 | return this; 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | return "ClusterGroupEntity{" + 84 | "machineId='" + machineId + '\'' + 85 | ", ip='" + ip + '\'' + 86 | ", port=" + port + 87 | ", clientSet=" + clientSet + 88 | ", belongToApp=" + belongToApp + 89 | '}'; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ClusterStateSingleVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.1 21 | */ 22 | public class ClusterStateSingleVO { 23 | 24 | private String address; 25 | private Integer mode; 26 | private String target; 27 | 28 | public String getAddress() { 29 | return address; 30 | } 31 | 32 | public ClusterStateSingleVO setAddress(String address) { 33 | this.address = address; 34 | return this; 35 | } 36 | 37 | public Integer getMode() { 38 | return mode; 39 | } 40 | 41 | public ClusterStateSingleVO setMode(Integer mode) { 42 | this.mode = mode; 43 | return this; 44 | } 45 | 46 | public String getTarget() { 47 | return target; 48 | } 49 | 50 | public ClusterStateSingleVO setTarget(String target) { 51 | this.target = target; 52 | return this; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return "ClusterStateSingleVO{" + 58 | "address='" + address + '\'' + 59 | ", mode=" + mode + 60 | ", target='" + target + '\'' + 61 | '}'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ConnectionDescriptorVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | 19 | /** 20 | * @author Eric Zhao 21 | * @since 1.4.0 22 | */ 23 | public class ConnectionDescriptorVO { 24 | 25 | private String address; 26 | private String host; 27 | 28 | public String getAddress() { 29 | return address; 30 | } 31 | 32 | public ConnectionDescriptorVO setAddress(String address) { 33 | this.address = address; 34 | return this; 35 | } 36 | 37 | public String getHost() { 38 | return host; 39 | } 40 | 41 | public ConnectionDescriptorVO setHost(String host) { 42 | this.host = host; 43 | return this; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "ConnectionDescriptorVO{" + 49 | "address='" + address + '\'' + 50 | ", host='" + host + '\'' + 51 | '}'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/ConnectionGroupVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * @author Eric Zhao 22 | * @since 1.4.0 23 | */ 24 | public class ConnectionGroupVO { 25 | 26 | private String namespace; 27 | private List connectionSet; 28 | private Integer connectedCount; 29 | 30 | public String getNamespace() { 31 | return namespace; 32 | } 33 | 34 | public ConnectionGroupVO setNamespace(String namespace) { 35 | this.namespace = namespace; 36 | return this; 37 | } 38 | 39 | public List getConnectionSet() { 40 | return connectionSet; 41 | } 42 | 43 | public ConnectionGroupVO setConnectionSet( 44 | List connectionSet) { 45 | this.connectionSet = connectionSet; 46 | return this; 47 | } 48 | 49 | public Integer getConnectedCount() { 50 | return connectedCount; 51 | } 52 | 53 | public ConnectionGroupVO setConnectedCount(Integer connectedCount) { 54 | this.connectedCount = connectedCount; 55 | return this; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "ConnectionGroupVO{" + 61 | "namespace='" + namespace + '\'' + 62 | ", connectionSet=" + connectionSet + 63 | ", connectedCount=" + connectedCount + 64 | '}'; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/config/ClusterClientConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.config; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.0 21 | */ 22 | public class ClusterClientConfig { 23 | 24 | private String serverHost; 25 | private Integer serverPort; 26 | 27 | private Integer requestTimeout; 28 | private Integer connectTimeout; 29 | 30 | public String getServerHost() { 31 | return serverHost; 32 | } 33 | 34 | public ClusterClientConfig setServerHost(String serverHost) { 35 | this.serverHost = serverHost; 36 | return this; 37 | } 38 | 39 | public Integer getServerPort() { 40 | return serverPort; 41 | } 42 | 43 | public ClusterClientConfig setServerPort(Integer serverPort) { 44 | this.serverPort = serverPort; 45 | return this; 46 | } 47 | 48 | public Integer getRequestTimeout() { 49 | return requestTimeout; 50 | } 51 | 52 | public ClusterClientConfig setRequestTimeout(Integer requestTimeout) { 53 | this.requestTimeout = requestTimeout; 54 | return this; 55 | } 56 | 57 | public Integer getConnectTimeout() { 58 | return connectTimeout; 59 | } 60 | 61 | public ClusterClientConfig setConnectTimeout(Integer connectTimeout) { 62 | this.connectTimeout = connectTimeout; 63 | return this; 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return "ClusterClientConfig{" + 69 | "serverHost='" + serverHost + '\'' + 70 | ", serverPort=" + serverPort + 71 | ", requestTimeout=" + requestTimeout + 72 | ", connectTimeout=" + connectTimeout + 73 | '}'; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/config/ServerTransportConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.config; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.0 21 | */ 22 | public class ServerTransportConfig { 23 | 24 | public static final int DEFAULT_PORT = 18730; 25 | public static final int DEFAULT_IDLE_SECONDS = 600; 26 | 27 | private Integer port; 28 | private Integer idleSeconds; 29 | 30 | public ServerTransportConfig() { 31 | this(DEFAULT_PORT, DEFAULT_IDLE_SECONDS); 32 | } 33 | 34 | public ServerTransportConfig(Integer port, Integer idleSeconds) { 35 | this.port = port; 36 | this.idleSeconds = idleSeconds; 37 | } 38 | 39 | public Integer getPort() { 40 | return port; 41 | } 42 | 43 | public ServerTransportConfig setPort(Integer port) { 44 | this.port = port; 45 | return this; 46 | } 47 | 48 | public Integer getIdleSeconds() { 49 | return idleSeconds; 50 | } 51 | 52 | public ServerTransportConfig setIdleSeconds(Integer idleSeconds) { 53 | this.idleSeconds = idleSeconds; 54 | return this; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return "ServerTransportConfig{" + 60 | "port=" + port + 61 | ", idleSeconds=" + idleSeconds + 62 | '}'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/request/ClusterClientModifyRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.request; 17 | 18 | import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ClusterClientConfig; 19 | 20 | /** 21 | * @author Eric Zhao 22 | * @since 1.4.0 23 | */ 24 | public class ClusterClientModifyRequest implements ClusterModifyRequest { 25 | 26 | private String app; 27 | private String ip; 28 | private Integer port; 29 | 30 | private Integer mode; 31 | private ClusterClientConfig clientConfig; 32 | 33 | @Override 34 | public String getApp() { 35 | return app; 36 | } 37 | 38 | public ClusterClientModifyRequest setApp(String app) { 39 | this.app = app; 40 | return this; 41 | } 42 | 43 | @Override 44 | public String getIp() { 45 | return ip; 46 | } 47 | 48 | public ClusterClientModifyRequest setIp(String ip) { 49 | this.ip = ip; 50 | return this; 51 | } 52 | 53 | @Override 54 | public Integer getPort() { 55 | return port; 56 | } 57 | 58 | public ClusterClientModifyRequest setPort(Integer port) { 59 | this.port = port; 60 | return this; 61 | } 62 | 63 | @Override 64 | public Integer getMode() { 65 | return mode; 66 | } 67 | 68 | public ClusterClientModifyRequest setMode(Integer mode) { 69 | this.mode = mode; 70 | return this; 71 | } 72 | 73 | public ClusterClientConfig getClientConfig() { 74 | return clientConfig; 75 | } 76 | 77 | public ClusterClientModifyRequest setClientConfig( 78 | ClusterClientConfig clientConfig) { 79 | this.clientConfig = clientConfig; 80 | return this; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/request/ClusterModifyRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.request; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.0 21 | */ 22 | public interface ClusterModifyRequest { 23 | 24 | String getApp(); 25 | 26 | String getIp(); 27 | 28 | Integer getPort(); 29 | 30 | Integer getMode(); 31 | } 32 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/state/AppClusterClientStateWrapVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.state; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.1 21 | */ 22 | public class AppClusterClientStateWrapVO { 23 | 24 | /** 25 | * {ip}@{transport_command_port}. 26 | */ 27 | private String id; 28 | 29 | private Integer commandPort; 30 | private String ip; 31 | 32 | private ClusterClientStateVO state; 33 | 34 | public String getId() { 35 | return id; 36 | } 37 | 38 | public AppClusterClientStateWrapVO setId(String id) { 39 | this.id = id; 40 | return this; 41 | } 42 | 43 | public String getIp() { 44 | return ip; 45 | } 46 | 47 | public AppClusterClientStateWrapVO setIp(String ip) { 48 | this.ip = ip; 49 | return this; 50 | } 51 | 52 | public ClusterClientStateVO getState() { 53 | return state; 54 | } 55 | 56 | public AppClusterClientStateWrapVO setState(ClusterClientStateVO state) { 57 | this.state = state; 58 | return this; 59 | } 60 | 61 | public Integer getCommandPort() { 62 | return commandPort; 63 | } 64 | 65 | public AppClusterClientStateWrapVO setCommandPort(Integer commandPort) { 66 | this.commandPort = commandPort; 67 | return this; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "AppClusterClientStateWrapVO{" + 73 | "id='" + id + '\'' + 74 | ", commandPort=" + commandPort + 75 | ", ip='" + ip + '\'' + 76 | ", state=" + state + 77 | '}'; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/state/AppClusterServerStateWrapVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.state; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.1 21 | */ 22 | public class AppClusterServerStateWrapVO { 23 | 24 | /** 25 | * {ip}@{transport_command_port}. 26 | */ 27 | private String id; 28 | 29 | private String ip; 30 | private Integer port; 31 | 32 | private Integer connectedCount; 33 | 34 | private Boolean belongToApp; 35 | 36 | private ClusterServerStateVO state; 37 | 38 | public String getId() { 39 | return id; 40 | } 41 | 42 | public AppClusterServerStateWrapVO setId(String id) { 43 | this.id = id; 44 | return this; 45 | } 46 | 47 | public String getIp() { 48 | return ip; 49 | } 50 | 51 | public AppClusterServerStateWrapVO setIp(String ip) { 52 | this.ip = ip; 53 | return this; 54 | } 55 | 56 | public Integer getPort() { 57 | return port; 58 | } 59 | 60 | public AppClusterServerStateWrapVO setPort(Integer port) { 61 | this.port = port; 62 | return this; 63 | } 64 | 65 | public Boolean getBelongToApp() { 66 | return belongToApp; 67 | } 68 | 69 | public AppClusterServerStateWrapVO setBelongToApp(Boolean belongToApp) { 70 | this.belongToApp = belongToApp; 71 | return this; 72 | } 73 | 74 | public Integer getConnectedCount() { 75 | return connectedCount; 76 | } 77 | 78 | public AppClusterServerStateWrapVO setConnectedCount(Integer connectedCount) { 79 | this.connectedCount = connectedCount; 80 | return this; 81 | } 82 | 83 | public ClusterServerStateVO getState() { 84 | return state; 85 | } 86 | 87 | public AppClusterServerStateWrapVO setState(ClusterServerStateVO state) { 88 | this.state = state; 89 | return this; 90 | } 91 | 92 | @Override 93 | public String toString() { 94 | return "AppClusterServerStateWrapVO{" + 95 | "id='" + id + '\'' + 96 | ", ip='" + ip + '\'' + 97 | ", port='" + port + '\'' + 98 | ", belongToApp=" + belongToApp + 99 | ", state=" + state + 100 | '}'; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/state/ClusterClientStateVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.state; 17 | 18 | import com.alibaba.csp.sentinel.dashboard.domain.cluster.ClusterClientInfoVO; 19 | 20 | /** 21 | * @author Eric Zhao 22 | * @since 1.4.0 23 | */ 24 | public class ClusterClientStateVO { 25 | 26 | /** 27 | * Cluster token client state. 28 | */ 29 | private ClusterClientInfoVO clientConfig; 30 | 31 | public ClusterClientInfoVO getClientConfig() { 32 | return clientConfig; 33 | } 34 | 35 | public ClusterClientStateVO setClientConfig(ClusterClientInfoVO clientConfig) { 36 | this.clientConfig = clientConfig; 37 | return this; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "ClusterClientStateVO{" + 43 | "clientConfig=" + clientConfig + 44 | '}'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/state/ClusterRequestLimitVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.state; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.1 21 | */ 22 | public class ClusterRequestLimitVO { 23 | 24 | private String namespace; 25 | private Double currentQps; 26 | private Double maxAllowedQps; 27 | 28 | public String getNamespace() { 29 | return namespace; 30 | } 31 | 32 | public ClusterRequestLimitVO setNamespace(String namespace) { 33 | this.namespace = namespace; 34 | return this; 35 | } 36 | 37 | public Double getCurrentQps() { 38 | return currentQps; 39 | } 40 | 41 | public ClusterRequestLimitVO setCurrentQps(Double currentQps) { 42 | this.currentQps = currentQps; 43 | return this; 44 | } 45 | 46 | public Double getMaxAllowedQps() { 47 | return maxAllowedQps; 48 | } 49 | 50 | public ClusterRequestLimitVO setMaxAllowedQps(Double maxAllowedQps) { 51 | this.maxAllowedQps = maxAllowedQps; 52 | return this; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return "ClusterRequestLimitVO{" + 58 | "namespace='" + namespace + '\'' + 59 | ", currentQps=" + currentQps + 60 | ", maxAllowedQps=" + maxAllowedQps + 61 | '}'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/state/ClusterStateSimpleEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.state; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.0 21 | */ 22 | public class ClusterStateSimpleEntity { 23 | 24 | private Integer mode; 25 | private Long lastModified; 26 | private Boolean clientAvailable; 27 | private Boolean serverAvailable; 28 | 29 | public Integer getMode() { 30 | return mode; 31 | } 32 | 33 | public ClusterStateSimpleEntity setMode(Integer mode) { 34 | this.mode = mode; 35 | return this; 36 | } 37 | 38 | public Long getLastModified() { 39 | return lastModified; 40 | } 41 | 42 | public ClusterStateSimpleEntity setLastModified(Long lastModified) { 43 | this.lastModified = lastModified; 44 | return this; 45 | } 46 | 47 | public Boolean getClientAvailable() { 48 | return clientAvailable; 49 | } 50 | 51 | public ClusterStateSimpleEntity setClientAvailable(Boolean clientAvailable) { 52 | this.clientAvailable = clientAvailable; 53 | return this; 54 | } 55 | 56 | public Boolean getServerAvailable() { 57 | return serverAvailable; 58 | } 59 | 60 | public ClusterStateSimpleEntity setServerAvailable(Boolean serverAvailable) { 61 | this.serverAvailable = serverAvailable; 62 | return this; 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return "ClusterStateSimpleEntity{" + 68 | "mode=" + mode + 69 | ", lastModified=" + lastModified + 70 | ", clientAvailable=" + clientAvailable + 71 | ", serverAvailable=" + serverAvailable + 72 | '}'; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/state/ClusterUniversalStatePairVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.state; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.1 21 | */ 22 | public class ClusterUniversalStatePairVO { 23 | 24 | private String ip; 25 | private Integer commandPort; 26 | 27 | private ClusterUniversalStateVO state; 28 | 29 | public ClusterUniversalStatePairVO() {} 30 | 31 | public ClusterUniversalStatePairVO(String ip, Integer commandPort, ClusterUniversalStateVO state) { 32 | this.ip = ip; 33 | this.commandPort = commandPort; 34 | this.state = state; 35 | } 36 | 37 | public String getIp() { 38 | return ip; 39 | } 40 | 41 | public ClusterUniversalStatePairVO setIp(String ip) { 42 | this.ip = ip; 43 | return this; 44 | } 45 | 46 | public Integer getCommandPort() { 47 | return commandPort; 48 | } 49 | 50 | public ClusterUniversalStatePairVO setCommandPort(Integer commandPort) { 51 | this.commandPort = commandPort; 52 | return this; 53 | } 54 | 55 | public ClusterUniversalStateVO getState() { 56 | return state; 57 | } 58 | 59 | public ClusterUniversalStatePairVO setState(ClusterUniversalStateVO state) { 60 | this.state = state; 61 | return this; 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return "ClusterUniversalStatePairVO{" + 67 | "ip='" + ip + '\'' + 68 | ", commandPort=" + commandPort + 69 | ", state=" + state + 70 | '}'; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/cluster/state/ClusterUniversalStateVO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.cluster.state; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.0 21 | */ 22 | public class ClusterUniversalStateVO { 23 | 24 | private ClusterStateSimpleEntity stateInfo; 25 | private ClusterClientStateVO client; 26 | private ClusterServerStateVO server; 27 | 28 | public ClusterClientStateVO getClient() { 29 | return client; 30 | } 31 | 32 | public ClusterUniversalStateVO setClient(ClusterClientStateVO client) { 33 | this.client = client; 34 | return this; 35 | } 36 | 37 | public ClusterServerStateVO getServer() { 38 | return server; 39 | } 40 | 41 | public ClusterUniversalStateVO setServer(ClusterServerStateVO server) { 42 | this.server = server; 43 | return this; 44 | } 45 | 46 | public ClusterStateSimpleEntity getStateInfo() { 47 | return stateInfo; 48 | } 49 | 50 | public ClusterUniversalStateVO setStateInfo( 51 | ClusterStateSimpleEntity stateInfo) { 52 | this.stateInfo = stateInfo; 53 | return this; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "ClusterUniversalStateVO{" + 59 | "stateInfo=" + stateInfo + 60 | ", client=" + client + 61 | ", server=" + server + 62 | '}'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/vo/gateway/api/AddApiReqVo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * Value Object for add gateway api. 22 | * 23 | * @author cdfive 24 | * @since 1.7.0 25 | */ 26 | public class AddApiReqVo { 27 | 28 | private String app; 29 | 30 | private String ip; 31 | 32 | private Integer port; 33 | 34 | private String apiName; 35 | 36 | private List predicateItems; 37 | 38 | public String getApp() { 39 | return app; 40 | } 41 | 42 | public void setApp(String app) { 43 | this.app = app; 44 | } 45 | 46 | public String getIp() { 47 | return ip; 48 | } 49 | 50 | public void setIp(String ip) { 51 | this.ip = ip; 52 | } 53 | 54 | public Integer getPort() { 55 | return port; 56 | } 57 | 58 | public void setPort(Integer port) { 59 | this.port = port; 60 | } 61 | 62 | public String getApiName() { 63 | return apiName; 64 | } 65 | 66 | public void setApiName(String apiName) { 67 | this.apiName = apiName; 68 | } 69 | 70 | public List getPredicateItems() { 71 | return predicateItems; 72 | } 73 | 74 | public void setPredicateItems(List predicateItems) { 75 | this.predicateItems = predicateItems; 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/vo/gateway/api/ApiPredicateItemVo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api; 17 | 18 | /** 19 | * Value Object for add or update gateway api. 20 | * 21 | * @author cdfive 22 | * @since 1.7.0 23 | */ 24 | public class ApiPredicateItemVo { 25 | 26 | private String pattern; 27 | 28 | private Integer matchStrategy; 29 | 30 | public String getPattern() { 31 | return pattern; 32 | } 33 | 34 | public void setPattern(String pattern) { 35 | this.pattern = pattern; 36 | } 37 | 38 | public Integer getMatchStrategy() { 39 | return matchStrategy; 40 | } 41 | 42 | public void setMatchStrategy(Integer matchStrategy) { 43 | this.matchStrategy = matchStrategy; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/vo/gateway/api/UpdateApiReqVo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * Value Object for update gateway api. 22 | * 23 | * @author cdfive 24 | * @since 1.7.0 25 | */ 26 | public class UpdateApiReqVo { 27 | 28 | private Long id; 29 | 30 | private String app; 31 | 32 | private List predicateItems; 33 | 34 | public Long getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Long id) { 39 | this.id = id; 40 | } 41 | 42 | public String getApp() { 43 | return app; 44 | } 45 | 46 | public void setApp(String app) { 47 | this.app = app; 48 | } 49 | 50 | public List getPredicateItems() { 51 | return predicateItems; 52 | } 53 | 54 | public void setPredicateItems(List predicateItems) { 55 | this.predicateItems = predicateItems; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/vo/gateway/rule/GatewayParamFlowItemVo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.rule; 17 | 18 | /** 19 | * Value Object for add or update gateway flow rule. 20 | * 21 | * @author cdfive 22 | * @since 1.7.0 23 | */ 24 | public class GatewayParamFlowItemVo { 25 | 26 | private Integer parseStrategy; 27 | 28 | private String fieldName; 29 | 30 | private String pattern; 31 | 32 | private Integer matchStrategy; 33 | 34 | public Integer getParseStrategy() { 35 | return parseStrategy; 36 | } 37 | 38 | public void setParseStrategy(Integer parseStrategy) { 39 | this.parseStrategy = parseStrategy; 40 | } 41 | 42 | public String getFieldName() { 43 | return fieldName; 44 | } 45 | 46 | public void setFieldName(String fieldName) { 47 | this.fieldName = fieldName; 48 | } 49 | 50 | public String getPattern() { 51 | return pattern; 52 | } 53 | 54 | public void setPattern(String pattern) { 55 | this.pattern = pattern; 56 | } 57 | 58 | public Integer getMatchStrategy() { 59 | return matchStrategy; 60 | } 61 | 62 | public void setMatchStrategy(Integer matchStrategy) { 63 | this.matchStrategy = matchStrategy; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/gateway/InMemApiDefinitionStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.gateway; 17 | 18 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity; 19 | import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter; 20 | import org.springframework.stereotype.Component; 21 | 22 | import java.util.concurrent.atomic.AtomicLong; 23 | 24 | /** 25 | * Store {@link ApiDefinitionEntity} in memory. 26 | * 27 | * @author cdfive 28 | * @since 1.7.0 29 | */ 30 | @Component 31 | public class InMemApiDefinitionStore extends InMemoryRuleRepositoryAdapter { 32 | 33 | private static AtomicLong ids = new AtomicLong(0); 34 | 35 | @Override 36 | protected long nextId() { 37 | return ids.incrementAndGet(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/gateway/InMemGatewayFlowRuleStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.gateway; 17 | 18 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity; 19 | import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter; 20 | import org.springframework.stereotype.Component; 21 | 22 | import java.util.concurrent.atomic.AtomicLong; 23 | 24 | /** 25 | * Store {@link GatewayFlowRuleEntity} in memory. 26 | * 27 | * @author cdfive 28 | * @since 1.7.0 29 | */ 30 | @Component 31 | public class InMemGatewayFlowRuleStore extends InMemoryRuleRepositoryAdapter { 32 | 33 | private static AtomicLong ids = new AtomicLong(0); 34 | 35 | @Override 36 | protected long nextId() { 37 | return ids.incrementAndGet(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/metric/MetricsRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.metric; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * Repository interface for aggregated metrics data. 22 | * 23 | * @param type of metrics 24 | * @author Eric Zhao 25 | */ 26 | public interface MetricsRepository { 27 | 28 | /** 29 | * Save the metric to the storage repository. 30 | * 31 | * @param metric metric data to save 32 | */ 33 | void save(T metric); 34 | 35 | /** 36 | * Save all metrics to the storage repository. 37 | * 38 | * @param metrics metrics to save 39 | */ 40 | void saveAll(Iterable metrics); 41 | 42 | /** 43 | * Get all metrics by {@code appName} and {@code resourceName} between a period of time. 44 | * 45 | * @param app application name for Sentinel 46 | * @param resource resource name 47 | * @param startTime start timestamp 48 | * @param endTime end timestamp 49 | * @return all metrics in query conditions 50 | */ 51 | List queryByAppAndResourceBetween(String app, String resource, long startTime, long endTime); 52 | 53 | /** 54 | * List resource name of provided application name. 55 | * 56 | * @param app application name 57 | * @return list of resources 58 | */ 59 | List listResourcesOfApp(String app); 60 | } 61 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/rule/InMemAuthorityRuleStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.rule; 17 | 18 | import java.util.concurrent.atomic.AtomicLong; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity; 21 | 22 | import org.springframework.stereotype.Component; 23 | 24 | /** 25 | * In-memory storage for authority rules. 26 | * 27 | * @author Eric Zhao 28 | * @since 0.2.1 29 | */ 30 | @Component 31 | public class InMemAuthorityRuleStore extends InMemoryRuleRepositoryAdapter { 32 | 33 | private static AtomicLong ids = new AtomicLong(0); 34 | 35 | @Override 36 | protected long nextId() { 37 | return ids.incrementAndGet(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/rule/InMemDegradeRuleStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.rule; 17 | 18 | import java.util.concurrent.atomic.AtomicLong; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity; 21 | 22 | import org.springframework.stereotype.Component; 23 | 24 | /** 25 | * @author leyou 26 | */ 27 | @Component 28 | public class InMemDegradeRuleStore extends InMemoryRuleRepositoryAdapter { 29 | 30 | private static AtomicLong ids = new AtomicLong(0); 31 | 32 | @Override 33 | protected long nextId() { 34 | return ids.incrementAndGet(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/rule/InMemFlowRuleStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.rule; 17 | 18 | import java.util.concurrent.atomic.AtomicLong; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; 21 | import com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig; 22 | 23 | import org.springframework.stereotype.Component; 24 | 25 | /** 26 | * Store {@link FlowRuleEntity} in memory. 27 | * 28 | * @author leyou 29 | */ 30 | @Component 31 | public class InMemFlowRuleStore extends InMemoryRuleRepositoryAdapter { 32 | 33 | private static AtomicLong ids = new AtomicLong(0); 34 | 35 | @Override 36 | protected long nextId() { 37 | return ids.incrementAndGet(); 38 | } 39 | 40 | @Override 41 | protected FlowRuleEntity preProcess(FlowRuleEntity entity) { 42 | if (entity != null && entity.isClusterMode()) { 43 | ClusterFlowConfig config = entity.getClusterConfig(); 44 | if (config == null) { 45 | config = new ClusterFlowConfig(); 46 | entity.setClusterConfig(config); 47 | } 48 | // Set cluster rule id. 49 | config.setFlowId(entity.getId()); 50 | } 51 | return entity; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/rule/InMemParamFlowRuleStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.rule; 17 | 18 | import java.util.concurrent.atomic.AtomicLong; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; 21 | import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowClusterConfig; 22 | 23 | import org.springframework.stereotype.Component; 24 | 25 | /** 26 | * @author Eric Zhao 27 | * @since 0.2.1 28 | */ 29 | @Component 30 | public class InMemParamFlowRuleStore extends InMemoryRuleRepositoryAdapter { 31 | 32 | private static AtomicLong ids = new AtomicLong(0); 33 | 34 | @Override 35 | protected long nextId() { 36 | return ids.incrementAndGet(); 37 | } 38 | 39 | @Override 40 | protected ParamFlowRuleEntity preProcess(ParamFlowRuleEntity entity) { 41 | if (entity != null && entity.isClusterMode()) { 42 | ParamFlowClusterConfig config = entity.getClusterConfig(); 43 | if (config == null) { 44 | config = new ParamFlowClusterConfig(); 45 | } 46 | // Set cluster rule id. 47 | config.setFlowId(entity.getId()); 48 | } 49 | return entity; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/rule/InMemSystemRuleStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.rule; 17 | 18 | import java.util.concurrent.atomic.AtomicLong; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity; 21 | 22 | import org.springframework.stereotype.Component; 23 | 24 | /** 25 | * @author leyou 26 | */ 27 | @Component 28 | public class InMemSystemRuleStore extends InMemoryRuleRepositoryAdapter { 29 | 30 | private static AtomicLong ids = new AtomicLong(0); 31 | 32 | @Override 33 | protected long nextId() { 34 | return ids.incrementAndGet(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/repository/rule/RuleRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.repository.rule; 17 | 18 | import java.util.List; 19 | 20 | import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; 21 | 22 | /** 23 | * Interface to store and find rules. 24 | * 25 | * @author leyou 26 | */ 27 | public interface RuleRepository { 28 | 29 | /** 30 | * Save one. 31 | * 32 | * @param entity 33 | * @return 34 | */ 35 | T save(T entity); 36 | 37 | /** 38 | * Save all. 39 | * 40 | * @param rules 41 | * @return rules saved. 42 | */ 43 | List saveAll(List rules); 44 | 45 | /** 46 | * Delete by id 47 | * 48 | * @param id 49 | * @return entity deleted 50 | */ 51 | T delete(ID id); 52 | 53 | /** 54 | * Find by id. 55 | * 56 | * @param id 57 | * @return 58 | */ 59 | T findById(ID id); 60 | 61 | /** 62 | * Find all by machine. 63 | * 64 | * @param machineInfo 65 | * @return 66 | */ 67 | List findAllByMachine(MachineInfo machineInfo); 68 | 69 | /** 70 | * Find all by application. 71 | * 72 | * @param appName valid app name 73 | * @return all rules of the application 74 | * @since 1.4.0 75 | */ 76 | List findAllByApp(String appName); 77 | 78 | ///** 79 | // * Find all by app and enable switch. 80 | // * @param app 81 | // * @param enable 82 | // * @return 83 | // */ 84 | //List findAllByAppAndEnable(String app, boolean enable); 85 | } 86 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/DynamicRuleProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.rule; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.0 21 | */ 22 | public interface DynamicRuleProvider { 23 | 24 | T getRules(String appName) throws Exception; 25 | } 26 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/DynamicRulePublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.rule; 17 | 18 | /** 19 | * @author Eric Zhao 20 | * @since 1.4.0 21 | */ 22 | public interface DynamicRulePublisher { 23 | 24 | /** 25 | * Publish rules to remote rule configuration center for given application name. 26 | * 27 | * @param app app name 28 | * @param rules list of rules to push 29 | * @throws Exception if some error occurs 30 | */ 31 | void publish(String app, T rules) throws Exception; 32 | } 33 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/FlowRuleApiProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.rule; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import java.util.stream.Collectors; 21 | 22 | import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; 23 | import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement; 24 | import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; 25 | import com.alibaba.csp.sentinel.util.StringUtil; 26 | 27 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; 28 | 29 | import org.springframework.beans.factory.annotation.Autowired; 30 | import org.springframework.stereotype.Component; 31 | 32 | /** 33 | * @author Eric Zhao 34 | */ 35 | @Component("flowRuleDefaultProvider") 36 | public class FlowRuleApiProvider implements DynamicRuleProvider> { 37 | 38 | @Autowired 39 | private SentinelApiClient sentinelApiClient; 40 | @Autowired 41 | private AppManagement appManagement; 42 | 43 | @Override 44 | public List getRules(String appName) throws Exception { 45 | if (StringUtil.isBlank(appName)) { 46 | return new ArrayList<>(); 47 | } 48 | List list = appManagement.getDetailApp(appName).getMachines() 49 | .stream() 50 | .filter(MachineInfo::isHealthy) 51 | .sorted((e1, e2) -> Long.compare(e2.getLastHeartbeat(), e1.getLastHeartbeat())).collect(Collectors.toList()); 52 | if (list.isEmpty()) { 53 | return new ArrayList<>(); 54 | } else { 55 | MachineInfo machine = list.get(0); 56 | return sentinelApiClient.fetchFlowRuleOfMachine(machine.getApp(), machine.getIp(), machine.getPort()); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/FlowRuleApiPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.rule; 17 | 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; 22 | import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement; 23 | import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; 24 | import com.alibaba.csp.sentinel.util.StringUtil; 25 | 26 | import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.stereotype.Component; 29 | 30 | /** 31 | * @author Eric Zhao 32 | * @since 1.4.0 33 | */ 34 | @Component("flowRuleDefaultPublisher") 35 | public class FlowRuleApiPublisher implements DynamicRulePublisher> { 36 | 37 | @Autowired 38 | private SentinelApiClient sentinelApiClient; 39 | @Autowired 40 | private AppManagement appManagement; 41 | 42 | @Override 43 | public void publish(String app, List rules) throws Exception { 44 | if (StringUtil.isBlank(app)) { 45 | return; 46 | } 47 | if (rules == null) { 48 | return; 49 | } 50 | Set set = appManagement.getDetailApp(app).getMachines(); 51 | 52 | for (MachineInfo machine : set) { 53 | if (!machine.isHealthy()) { 54 | continue; 55 | } 56 | // TODO: parse the results 57 | sentinelApiClient.setFlowRuleOfMachine(app, machine.getIp(), machine.getPort(), rules); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/service/ClusterAssignService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.service; 17 | 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | import com.alibaba.csp.sentinel.dashboard.domain.cluster.ClusterAppAssignResultVO; 22 | import com.alibaba.csp.sentinel.dashboard.domain.cluster.request.ClusterAppAssignMap; 23 | 24 | /** 25 | * @author Eric Zhao 26 | * @since 1.4.1 27 | */ 28 | public interface ClusterAssignService { 29 | 30 | /** 31 | * Unbind a specific cluster server and its clients. 32 | * 33 | * @param app app name 34 | * @param machineId valid machine ID ({@code host@commandPort}) 35 | * @return assign result 36 | */ 37 | ClusterAppAssignResultVO unbindClusterServer(String app, String machineId); 38 | 39 | /** 40 | * Unbind a set of cluster servers and its clients. 41 | * 42 | * @param app app name 43 | * @param machineIdSet set of valid machine ID ({@code host@commandPort}) 44 | * @return assign result 45 | */ 46 | ClusterAppAssignResultVO unbindClusterServers(String app, Set machineIdSet); 47 | 48 | /** 49 | * Apply cluster server and client assignment for provided app. 50 | * 51 | * @param app app name 52 | * @param clusterMap cluster assign map (server -> clients) 53 | * @param remainingSet unassigned set of machine ID 54 | * @return assign result 55 | */ 56 | ClusterAppAssignResultVO applyAssignToApp(String app, List clusterMap, 57 | Set remainingSet); 58 | } 59 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/util/AsyncUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.util; 17 | 18 | import java.util.List; 19 | import java.util.Objects; 20 | import java.util.concurrent.CompletableFuture; 21 | import java.util.concurrent.TimeUnit; 22 | import java.util.stream.Collectors; 23 | 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | /** 28 | * @author Eric Zhao 29 | * @since 1.4.1 30 | */ 31 | public final class AsyncUtils { 32 | 33 | private static final Logger LOG = LoggerFactory.getLogger(AsyncUtils.class); 34 | 35 | public static CompletableFuture newFailedFuture(Throwable ex) { 36 | CompletableFuture future = new CompletableFuture<>(); 37 | future.completeExceptionally(ex); 38 | return future; 39 | } 40 | 41 | public static CompletableFuture> sequenceFuture(List> futures) { 42 | return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) 43 | .thenApply(v -> futures.stream() 44 | .map(AsyncUtils::getValue) 45 | .filter(Objects::nonNull) 46 | .collect(Collectors.toList()) 47 | ); 48 | } 49 | 50 | public static CompletableFuture> sequenceSuccessFuture(List> futures) { 51 | return CompletableFuture.supplyAsync(() -> futures.parallelStream() 52 | .map(AsyncUtils::getValue) 53 | .filter(Objects::nonNull) 54 | .collect(Collectors.toList()) 55 | ); 56 | } 57 | 58 | public static T getValue(CompletableFuture future) { 59 | try { 60 | return future.get(10, TimeUnit.SECONDS); 61 | } catch (Exception ex) { 62 | LOG.error("getValue for async result failed", ex); 63 | } 64 | return null; 65 | } 66 | 67 | public static boolean isSuccessFuture(CompletableFuture future) { 68 | return future.isDone() && !future.isCompletedExceptionally() && !future.isCancelled(); 69 | } 70 | 71 | private AsyncUtils() {} 72 | } 73 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/util/MachineUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.alibaba.csp.sentinel.dashboard.util; 17 | 18 | import java.util.Optional; 19 | 20 | import com.alibaba.csp.sentinel.util.StringUtil; 21 | import com.alibaba.csp.sentinel.util.function.Tuple2; 22 | 23 | /** 24 | * @author Eric Zhao 25 | */ 26 | public final class MachineUtils { 27 | 28 | public static Optional parseCommandPort(String machineIp) { 29 | try { 30 | if (!machineIp.contains("@")) { 31 | return Optional.empty(); 32 | } 33 | String[] str = machineIp.split("@"); 34 | if (str.length <= 1) { 35 | return Optional.empty(); 36 | } 37 | return Optional.of(Integer.parseInt(str[1])); 38 | } catch (Exception ex) { 39 | return Optional.empty(); 40 | } 41 | } 42 | 43 | public static Optional> parseCommandIpAndPort(String machineIp) { 44 | try { 45 | if (StringUtil.isEmpty(machineIp) || !machineIp.contains("@")) { 46 | return Optional.empty(); 47 | } 48 | String[] str = machineIp.split("@"); 49 | if (str.length <= 1) { 50 | return Optional.empty(); 51 | } 52 | return Optional.of(Tuple2.of(str[0], Integer.parseInt(str[1]))); 53 | } catch (Exception ex) { 54 | return Optional.empty(); 55 | } 56 | } 57 | 58 | private MachineUtils() {} 59 | } 60 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=7001 2 | #spring settings 3 | spring.http.encoding.force=true 4 | spring.http.encoding.charset=UTF-8 5 | spring.http.encoding.enabled=true 6 | 7 | #logging settings 8 | logging.level.org.springframework.web=INFO 9 | logging.file=${user.home}/logs/csp/sentinel-dashboard.log 10 | logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 11 | #logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 12 | 13 | #auth settings 14 | auth.filter.exclude-urls=/,/auth/login,/auth/logout,/registry/machine 15 | auth.filter.exclude-url-suffixes=htm,html,js,css,map,ico,ttf,woff,png 16 | auth.username=sentinel 17 | auth.password=sentinel -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | tmp/ -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | * ENVIRONMENTS 4 | * ================= 5 | */ 6 | 7 | // Define globals exposed by modern browsers. 8 | "browser": true, 9 | 10 | // Define globals exposed by jQuery. 11 | "jquery": true, 12 | 13 | // Define globals exposed by Node.js. 14 | "node": true, 15 | 16 | // Allow ES6. 17 | "esversion": 6, 18 | 19 | /* 20 | * ENFORCING OPTIONS 21 | * ================= 22 | */ 23 | 24 | // Force all variable names to use either camelCase style or UPPER_CASE 25 | // with underscores. 26 | "camelcase": true, 27 | 28 | // Prohibit use of == and != in favor of === and !==. 29 | "eqeqeq": true, 30 | 31 | // Enforce tab width of 2 spaces. 32 | "indent": 2, 33 | 34 | // Prohibit use of a variable before it is defined. 35 | "latedef": true, 36 | 37 | // Enforce line length to 100 characters 38 | "maxlen": 100, 39 | 40 | // Require capitalized names for constructor functions. 41 | "newcap": true, 42 | 43 | // Enforce use of single quotation marks for strings. 44 | "quotmark": "single", 45 | 46 | // Enforce placing 'use strict' at the top function scope 47 | // 前端项目中外层使用 strict 即可,覆盖此条规则 48 | "strict": false, 49 | 50 | // Prohibit use of explicitly undeclared variables. 51 | "undef": true, 52 | 53 | // Warn when variables are defined but never used. 54 | "unused": true, 55 | 56 | /* 57 | * RELAXING OPTIONS 58 | * ================= 59 | */ 60 | 61 | // Suppress warnings about == null comparisons. 62 | "eqnull": true, 63 | "globals": { 64 | "$": false, 65 | "angular": false 66 | } 67 | } -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/README.md: -------------------------------------------------------------------------------- 1 | # Sentinel Dashboard Frontend 2 | 3 | ## Env Requirement 4 | 5 | - Node.js > 6.x 6 | 7 | ## Code Guide 8 | 9 | - [Code Style Guide for HTML/CSS](https://codeguide.bootcss.com/) 10 | - [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript/tree/es5-deprecated/es5) 11 | 12 | ## Install Packages 13 | 14 | ``` 15 | npm install 16 | ``` 17 | 18 | ## Start Development 19 | 20 | ``` 21 | npm start 22 | ``` 23 | 24 | ## Build for production 25 | 26 | ``` 27 | npm run build 28 | ``` 29 | 30 | ## Credit 31 | 32 | - [sb-admin-angular](https://github.com/start-angular/sb-admin-angular) -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/README_zh.md: -------------------------------------------------------------------------------- 1 | # Sentinel Dashboard Frontend 2 | 3 | ## 环境要求 4 | 5 | - Node.js > 6.x 6 | 7 | ## 编码规范 8 | 9 | - HTML/CSS 遵循 [Bootstrap 编码规范](https://codeguide.bootcss.com/) 10 | - JavaScript 遵循 [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript/tree/es5-deprecated/es5) 以及最新的 ES 6 标准 11 | 12 | ## 安装依赖 13 | 14 | ``` 15 | npm i 16 | ``` 17 | 18 | ## 开始本地开发 19 | 20 | ``` 21 | npm start 22 | ``` 23 | 24 | ## 构建前端资源 25 | 26 | ``` 27 | npm run build 28 | ``` 29 | 30 | ## Credit 31 | 32 | - [sb-admin-angular](https://github.com/start-angular/sb-admin-angular) -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc function 3 | * @name sentinelDashboardApp.controller:MainCtrl 4 | * @description 5 | * # MainCtrl 6 | * Controller of the sentinelDashboardApp 7 | */ 8 | angular.module('sentinelDashboardApp') 9 | .controller('HomeCtrl', ['$scope', '$position', function ($scope, $position) { 10 | // do noting 11 | }]); 12 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/login.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.controller('LoginCtl', ['$scope', '$state', '$window', 'AuthService', 4 | function ($scope, $state, $window, AuthService) { 5 | // If auth passed, jump to the index page directly 6 | if ($window.localStorage.getItem('session_sentinel_admin')) { 7 | $state.go('dashboard'); 8 | } 9 | 10 | $scope.login = function () { 11 | if (!$scope.username) { 12 | alert('请输入用户名'); 13 | return; 14 | } 15 | 16 | if (!$scope.password) { 17 | alert('请输入密码'); 18 | return; 19 | } 20 | 21 | var param = {"username": $scope.username, "password": $scope.password}; 22 | 23 | AuthService.login(param).success(function (data) { 24 | if (data.code == 0) { 25 | $window.localStorage.setItem('session_sentinel_admin', { 26 | username: data.data 27 | }); 28 | 29 | $state.go('dashboard'); 30 | } else { 31 | alert(data.msg); 32 | } 33 | }); 34 | }; 35 | }] 36 | ); -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/machine.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.controller('MachineCtl', ['$scope', '$stateParams', 'MachineService', 4 | function ($scope, $stateParams, MachineService) { 5 | $scope.app = $stateParams.app; 6 | $scope.propertyName = ''; 7 | $scope.reverse = false; 8 | $scope.currentPage = 1; 9 | $scope.machines = []; 10 | $scope.machinesPageConfig = { 11 | pageSize: 10, 12 | currentPageIndex: 1, 13 | totalPage: 1, 14 | totalCount: 0, 15 | }; 16 | 17 | $scope.sortBy = function (propertyName) { 18 | // console.log('machine sortBy ' + propertyName); 19 | $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false; 20 | $scope.propertyName = propertyName; 21 | }; 22 | 23 | $scope.reloadMachines = function() { 24 | MachineService.getAppMachines($scope.app).success( 25 | function (data) { 26 | // console.log('get machines: ' + data.data[0].hostname) 27 | if (data.code == 0 && data.data) { 28 | $scope.machines = data.data; 29 | var healthy = 0; 30 | $scope.machines.forEach(function (item) { 31 | if (item.healthy) { 32 | healthy++; 33 | } 34 | if (!item.hostname) { 35 | item.hostname = '未知' 36 | } 37 | }) 38 | $scope.healthyCount = healthy; 39 | $scope.machinesPageConfig.totalCount = $scope.machines.length; 40 | } else { 41 | $scope.machines = []; 42 | $scope.healthyCount = 0; 43 | } 44 | } 45 | ); 46 | }; 47 | 48 | $scope.removeMachine = function(ip, port) { 49 | if (!confirm("confirm to remove machine [" + ip + ":" + port + "]?")) { 50 | return; 51 | } 52 | MachineService.removeAppMachine($scope.app, ip, port).success( 53 | function(data) { 54 | if (data.code == 0) { 55 | $scope.reloadMachines(); 56 | } else { 57 | alert("remove failed"); 58 | } 59 | } 60 | ); 61 | }; 62 | 63 | $scope.reloadMachines(); 64 | 65 | }]); 66 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc function 3 | * @name sentinelDashboardApp.controller:MainCtrl 4 | * @description 5 | * # MainCtrl 6 | * Controller of the sentinelDashboardApp 7 | */ 8 | angular.module('sentinelDashboardApp') 9 | .controller('DashboardCtrl', ['$scope', '$position', function ($scope, $position) { 10 | }]); 11 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/header/header.html: -------------------------------------------------------------------------------- 1 |
2 | 13 | 14 | 15 |
-------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/header/header.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name izzyposWebApp.directive:adminPosHeader 4 | * @description 5 | * # adminPosHeader 6 | */ 7 | angular.module('sentinelDashboardApp') 8 | .directive('header', ['AuthService', function () { 9 | return { 10 | templateUrl: 'app/scripts/directives/header/header.html', 11 | restrict: 'E', 12 | replace: true, 13 | controller: function ($scope, $state, $window, AuthService) { 14 | if (!$window.localStorage.getItem('session_sentinel_admin')) { 15 | $state.go('login'); 16 | } 17 | 18 | $scope.logout = function () { 19 | AuthService.logout().success(function (data) { 20 | if (data.code == 0) { 21 | $window.localStorage.removeItem("session_sentinel_admin"); 22 | $state.go('login'); 23 | } else { 24 | alert('logout error'); 25 | } 26 | }); 27 | } 28 | } 29 | } 30 | }]); 31 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar-search/sidebar-search.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar-search/sidebar-search.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name izzyposWebApp.directive:adminPosHeader 4 | * @description 5 | * # adminPosHeader 6 | */ 7 | 8 | angular.module('sentinelDashboardApp') 9 | .directive('sidebarSearch', function () { 10 | return { 11 | templateUrl: 'app/scripts/directives/sidebar/sidebar-search/sidebar-search.html', 12 | restrict: 'E', 13 | replace: true, 14 | scope: { 15 | }, 16 | controller: function ($scope) { 17 | $scope.selectedMenu = 'home'; 18 | } 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.js: -------------------------------------------------------------------------------- 1 | angular.module('sentinelDashboardApp') 2 | .directive('sidebar', ['$location', '$stateParams', 'AppService', function () { 3 | return { 4 | templateUrl: 'app/scripts/directives/sidebar/sidebar.html', 5 | restrict: 'E', 6 | replace: true, 7 | scope: { 8 | }, 9 | controller: function ($scope, $stateParams, $location, AppService) { 10 | $scope.app = $stateParams.app; 11 | $scope.collapseVar = 0; 12 | 13 | // app 14 | AppService.getApps().success( 15 | function (data) { 16 | if (data.code === 0) { 17 | let path = $location.path().split('/'); 18 | let initHashApp = path[path.length - 1]; 19 | $scope.apps = data.data; 20 | $scope.apps = $scope.apps.map(function (item) { 21 | if (item.app === initHashApp) { 22 | item.active = true; 23 | } 24 | let healthyCount = 0; 25 | for (let i in item.machines) { 26 | if (item.machines[i].healthy) { 27 | healthyCount++; 28 | } 29 | } 30 | item.healthyCount = healthyCount; 31 | // Handle appType 32 | item.isGateway = item.appType === 1 || item.appType === 11 || item.appType === 12; 33 | 34 | if (item.shown) { 35 | return item; 36 | } 37 | }); 38 | } 39 | } 40 | ); 41 | 42 | // toggle side bar 43 | $scope.click = function ($event) { 44 | let entry = angular.element($event.target).scope().entry; 45 | entry.active = !entry.active;// toggle this clicked app bar 46 | 47 | $scope.apps.forEach(function (item) { // collapse other app bars 48 | if (item !== entry) { 49 | item.active = false; 50 | } 51 | }); 52 | }; 53 | 54 | /** 55 | * @deprecated 56 | */ 57 | $scope.addSearchApp = function () { 58 | let findApp = false; 59 | for (let i = 0; i < $scope.apps.length; i++) { 60 | if ($scope.apps[i].app === $scope.searchApp) { 61 | findApp = true; 62 | break; 63 | } 64 | } 65 | if (!findApp) { 66 | $scope.apps.push({ app: $scope.searchApp }); 67 | } 68 | }; 69 | } 70 | }; 71 | }]); 72 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/filters/filters.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.filter('range', [function () { 4 | return function (input, length) { 5 | if (isNaN(length) || length <= 0) { 6 | return []; 7 | } 8 | 9 | input = []; 10 | for (var index = 1; index <= length; index++) { 11 | input.push(index); 12 | } 13 | 14 | return input; 15 | }; 16 | 17 | }]); 18 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/appservice.js: -------------------------------------------------------------------------------- 1 | 2 | var app = angular.module('sentinelDashboardApp'); 3 | 4 | app.service('AppService', ['$http', function ($http) { 5 | this.getApps = function () { 6 | return $http({ 7 | // url: 'app/mock_infos', 8 | url: 'app/briefinfos.json', 9 | method: 'GET' 10 | }); 11 | }; 12 | }]); 13 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/auth_service.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('AuthService', ['$http', function ($http) { 4 | this.login = function (param) { 5 | return $http({ 6 | url: '/auth/login', 7 | params: param, 8 | method: 'POST' 9 | }); 10 | }; 11 | 12 | this.logout = function () { 13 | return $http({ 14 | url: '/auth/logout', 15 | method: 'POST' 16 | }); 17 | }; 18 | }]); 19 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/authority_service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Authority rule service. 3 | */ 4 | angular.module('sentinelDashboardApp').service('AuthorityRuleService', ['$http', function ($http) { 5 | this.queryMachineRules = function(app, ip, port) { 6 | var param = { 7 | app: app, 8 | ip: ip, 9 | port: port 10 | }; 11 | return $http({ 12 | url: '/authority/rules', 13 | params: param, 14 | method: 'GET' 15 | }); 16 | }; 17 | 18 | this.addNewRule = function(rule) { 19 | return $http({ 20 | url: '/authority/rule', 21 | data: rule, 22 | method: 'POST' 23 | }); 24 | }; 25 | 26 | this.saveRule = function (entity) { 27 | return $http({ 28 | url: '/authority/rule/' + entity.id, 29 | data: entity, 30 | method: 'PUT' 31 | }); 32 | }; 33 | 34 | this.deleteRule = function (entity) { 35 | return $http({ 36 | url: '/authority/rule/' + entity.id, 37 | method: 'DELETE' 38 | }); 39 | }; 40 | 41 | this.checkRuleValid = function checkRuleValid(rule) { 42 | if (rule.resource === undefined || rule.resource === '') { 43 | alert('资源名称不能为空'); 44 | return false; 45 | } 46 | if (rule.limitApp === undefined || rule.limitApp === '') { 47 | alert('流控针对应用不能为空'); 48 | return false; 49 | } 50 | if (rule.strategy === undefined) { 51 | alert('必须选择黑白名单模式'); 52 | return false; 53 | } 54 | return true; 55 | }; 56 | }]); 57 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/cluster_state_service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Cluster state control service. 3 | * 4 | * @author Eric Zhao 5 | */ 6 | angular.module('sentinelDashboardApp').service('ClusterStateService', ['$http', function ($http) { 7 | 8 | this.fetchClusterUniversalStateSingle = function(app, ip, port) { 9 | var param = { 10 | app: app, 11 | ip: ip, 12 | port: port 13 | }; 14 | return $http({ 15 | url: '/cluster/state_single', 16 | params: param, 17 | method: 'GET' 18 | }); 19 | }; 20 | 21 | this.fetchClusterUniversalStateOfApp = function(app) { 22 | return $http({ 23 | url: '/cluster/state/' + app, 24 | method: 'GET' 25 | }); 26 | }; 27 | 28 | this.fetchClusterServerStateOfApp = function(app) { 29 | return $http({ 30 | url: '/cluster/server_state/' + app, 31 | method: 'GET' 32 | }); 33 | }; 34 | 35 | this.fetchClusterClientStateOfApp = function(app) { 36 | return $http({ 37 | url: '/cluster/client_state/' + app, 38 | method: 'GET' 39 | }); 40 | }; 41 | 42 | this.modifyClusterConfig = function(config) { 43 | return $http({ 44 | url: '/cluster/config/modify_single', 45 | data: config, 46 | method: 'POST' 47 | }); 48 | }; 49 | 50 | this.applyClusterFullAssignOfApp = function(app, clusterMap) { 51 | return $http({ 52 | url: '/cluster/assign/all_server/' + app, 53 | data: clusterMap, 54 | method: 'POST' 55 | }); 56 | }; 57 | 58 | this.applyClusterSingleServerAssignOfApp = function(app, request) { 59 | return $http({ 60 | url: '/cluster/assign/single_server/' + app, 61 | data: request, 62 | method: 'POST' 63 | }); 64 | }; 65 | 66 | this.applyClusterServerBatchUnbind = function(app, machineSet) { 67 | return $http({ 68 | url: '/cluster/assign/unbind_server/' + app, 69 | data: machineSet, 70 | method: 'POST' 71 | }); 72 | }; 73 | }]); 74 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/degradeservice.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('DegradeService', ['$http', function ($http) { 4 | this.queryMachineRules = function (app, ip, port) { 5 | var param = { 6 | app: app, 7 | ip: ip, 8 | port: port 9 | }; 10 | return $http({ 11 | url: 'degrade/rules.json', 12 | params: param, 13 | method: 'GET' 14 | }); 15 | }; 16 | 17 | this.newRule = function (rule) { 18 | var param = { 19 | id: rule.id, 20 | resource: rule.resource, 21 | limitApp: rule.limitApp, 22 | count: rule.count, 23 | timeWindow: rule.timeWindow, 24 | grade: rule.grade, 25 | app: rule.app, 26 | ip: rule.ip, 27 | port: rule.port 28 | }; 29 | return $http({ 30 | url: '/degrade/new.json', 31 | params: param, 32 | method: 'GET' 33 | }); 34 | }; 35 | 36 | this.saveRule = function (rule) { 37 | var param = { 38 | id: rule.id, 39 | resource: rule.resource, 40 | limitApp: rule.limitApp, 41 | grade: rule.grade, 42 | count: rule.count, 43 | timeWindow: rule.timeWindow, 44 | }; 45 | return $http({ 46 | url: '/degrade/save.json', 47 | params: param, 48 | method: 'GET' 49 | }); 50 | }; 51 | 52 | this.deleteRule = function (rule) { 53 | var param = { 54 | id: rule.id, 55 | app: rule.app 56 | }; 57 | return $http({ 58 | url: '/degrade/delete.json', 59 | params: param, 60 | method: 'GET' 61 | }); 62 | }; 63 | 64 | this.checkRuleValid = function (rule) { 65 | if (rule.resource === undefined || rule.resource === '') { 66 | alert('资源名称不能为空'); 67 | return false; 68 | } 69 | if (rule.grade === undefined || rule.grade < 0) { 70 | alert('未知的降级策略'); 71 | return false; 72 | } 73 | if (rule.count === undefined || rule.count === '' || rule.count < 0) { 74 | alert('降级阈值不能为空或小于 0'); 75 | return false; 76 | } 77 | if (rule.timeWindow === undefined || rule.timeWindow === '' || rule.timeWindow <= 0) { 78 | alert('降级时间窗口必须大于 0'); 79 | return false; 80 | } 81 | // 异常比率类型. 82 | if (rule.grade == 1 && rule.count > 1) { 83 | alert('异常比率超出范围:[0.0 - 1.0]'); 84 | return false; 85 | } 86 | return true; 87 | }; 88 | }]); 89 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flow_service_v2.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('FlowServiceV2', ['$http', function ($http) { 4 | this.queryMachineRules = function (app, ip, port) { 5 | var param = { 6 | app: app, 7 | ip: ip, 8 | port: port 9 | }; 10 | return $http({ 11 | url: '/v2/flow/rules', 12 | params: param, 13 | method: 'GET' 14 | }); 15 | }; 16 | 17 | this.newRule = function (rule) { 18 | return $http({ 19 | url: '/v2/flow/rule', 20 | data: rule, 21 | method: 'POST' 22 | }); 23 | }; 24 | 25 | this.saveRule = function (rule) { 26 | return $http({ 27 | url: '/v2/flow/rule/' + rule.id, 28 | data: rule, 29 | method: 'PUT' 30 | }); 31 | }; 32 | 33 | this.deleteRule = function (rule) { 34 | return $http({ 35 | url: '/v2/flow/rule/' + rule.id, 36 | method: 'DELETE' 37 | }); 38 | }; 39 | 40 | function notNumberAtLeastZero(num) { 41 | return num === undefined || num === '' || isNaN(num) || num < 0; 42 | } 43 | 44 | function notNumberGreaterThanZero(num) { 45 | return num === undefined || num === '' || isNaN(num) || num <= 0; 46 | } 47 | 48 | this.checkRuleValid = function (rule) { 49 | if (rule.resource === undefined || rule.resource === '') { 50 | alert('资源名称不能为空'); 51 | return false; 52 | } 53 | if (rule.count === undefined || rule.count < 0) { 54 | alert('限流阈值必须大于等于 0'); 55 | return false; 56 | } 57 | if (rule.strategy === undefined || rule.strategy < 0) { 58 | alert('无效的流控模式'); 59 | return false; 60 | } 61 | if (rule.strategy == 1 || rule.strategy == 2) { 62 | if (rule.refResource === undefined || rule.refResource == '') { 63 | alert('请填写关联资源或入口'); 64 | return false; 65 | } 66 | } 67 | if (rule.controlBehavior === undefined || rule.controlBehavior < 0) { 68 | alert('无效的流控整形方式'); 69 | return false; 70 | } 71 | if (rule.controlBehavior == 1 && notNumberGreaterThanZero(rule.warmUpPeriodSec)) { 72 | alert('预热时长必须大于 0'); 73 | return false; 74 | } 75 | if (rule.controlBehavior == 2 && notNumberGreaterThanZero(rule.maxQueueingTimeMs)) { 76 | alert('排队超时时间必须大于 0'); 77 | return false; 78 | } 79 | if (rule.clusterMode && (rule.clusterConfig === undefined || rule.clusterConfig.thresholdType === undefined)) { 80 | alert('集群限流配置不正确'); 81 | return false; 82 | } 83 | return true; 84 | }; 85 | }]); 86 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/gateway/api_service.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('GatewayApiService', ['$http', function ($http) { 4 | this.queryApis = function (app, ip, port) { 5 | var param = { 6 | app: app, 7 | ip: ip, 8 | port: port 9 | }; 10 | return $http({ 11 | url: '/gateway/api/list.json', 12 | params: param, 13 | method: 'GET' 14 | }); 15 | }; 16 | 17 | this.newApi = function (api) { 18 | return $http({ 19 | url: '/gateway/api/new.json', 20 | data: api, 21 | method: 'POST' 22 | }); 23 | }; 24 | 25 | this.saveApi = function (api) { 26 | return $http({ 27 | url: '/gateway/api/save.json', 28 | data: api, 29 | method: 'POST' 30 | }); 31 | }; 32 | 33 | this.deleteApi = function (api) { 34 | var param = { 35 | id: api.id, 36 | app: api.app 37 | }; 38 | return $http({ 39 | url: '/gateway/api/delete.json', 40 | params: param, 41 | method: 'POST' 42 | }); 43 | }; 44 | 45 | this.checkApiValid = function (api, apiNames) { 46 | if (api.apiName === undefined || api.apiName === '') { 47 | alert('API名称不能为空'); 48 | return false; 49 | } 50 | 51 | if (api.predicateItems == null || api.predicateItems.length === 0) { 52 | // Should never happen since no remove button will display when only one predicateItem. 53 | alert('至少有一个匹配规则'); 54 | return false; 55 | } 56 | 57 | for (var i = 0; i < api.predicateItems.length; i++) { 58 | var predicateItem = api.predicateItems[i]; 59 | var pattern = predicateItem.pattern; 60 | if (pattern === undefined || pattern === '') { 61 | alert('匹配串不能为空,请检查'); 62 | return false; 63 | } 64 | } 65 | 66 | if (apiNames.indexOf(api.apiName) !== -1) { 67 | alert('API名称(' + api.apiName + ')已存在'); 68 | return false; 69 | } 70 | 71 | return true; 72 | }; 73 | }]); 74 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/gateway/flow_service.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('GatewayFlowService', ['$http', function ($http) { 4 | this.queryRules = function (app, ip, port) { 5 | var param = { 6 | app: app, 7 | ip: ip, 8 | port: port 9 | }; 10 | 11 | return $http({ 12 | url: '/gateway/flow/list.json', 13 | params: param, 14 | method: 'GET' 15 | }); 16 | }; 17 | 18 | this.newRule = function (rule) { 19 | return $http({ 20 | url: '/gateway/flow/new.json', 21 | data: rule, 22 | method: 'POST' 23 | }); 24 | }; 25 | 26 | this.saveRule = function (rule) { 27 | return $http({ 28 | url: '/gateway/flow/save.json', 29 | data: rule, 30 | method: 'POST' 31 | }); 32 | }; 33 | 34 | this.deleteRule = function (rule) { 35 | var param = { 36 | id: rule.id, 37 | app: rule.app 38 | }; 39 | 40 | return $http({ 41 | url: '/gateway/flow/delete.json', 42 | params: param, 43 | method: 'POST' 44 | }); 45 | }; 46 | 47 | this.checkRuleValid = function (rule) { 48 | if (rule.resource === undefined || rule.resource === '') { 49 | alert('API名称不能为空'); 50 | return false; 51 | } 52 | 53 | if (rule.paramItem != null) { 54 | if (rule.paramItem.parseStrategy == 2 || 55 | rule.paramItem.parseStrategy == 3 || 56 | rule.paramItem.parseStrategy == 4) { 57 | if (rule.paramItem.fieldName === undefined || rule.paramItem.fieldName === '') { 58 | alert('当参数属性为Header、URL参数、Cookie时,参数名称不能为空'); 59 | return false; 60 | } 61 | 62 | if (rule.paramItem.pattern === '') { 63 | alert('匹配串不能为空'); 64 | return false; 65 | } 66 | } 67 | } 68 | 69 | if (rule.count === undefined || rule.count < 0) { 70 | alert((rule.grade === 1 ? 'QPS阈值' : '线程数') + '必须大于等于 0'); 71 | return false; 72 | } 73 | 74 | return true; 75 | }; 76 | }]); 77 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/identityservice.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('IdentityService', ['$http', function ($http) { 4 | 5 | this.fetchIdentityOfMachine = function (ip, port, searchKey) { 6 | var param = { 7 | ip: ip, 8 | port: port, 9 | searchKey: searchKey 10 | }; 11 | return $http({ 12 | url: 'resource/machineResource.json', 13 | params: param, 14 | method: 'GET' 15 | }); 16 | }; 17 | this.fetchClusterNodeOfMachine = function (ip, port, searchKey) { 18 | var param = { 19 | ip: ip, 20 | port: port, 21 | type: 'cluster', 22 | searchKey: searchKey 23 | }; 24 | return $http({ 25 | url: 'resource/machineResource.json', 26 | params: param, 27 | method: 'GET' 28 | }); 29 | }; 30 | }]); 31 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/machineservice.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('MachineService', ['$http', '$httpParamSerializerJQLike', 4 | function ($http, $httpParamSerializerJQLike) { 5 | this.getAppMachines = function (app) { 6 | return $http({ 7 | url: 'app/' + app + '/machines.json', 8 | method: 'GET' 9 | }); 10 | }; 11 | this.removeAppMachine = function (app, ip, port) { 12 | return $http({ 13 | url: 'app/' + app + '/machine/remove.json', 14 | method: 'POST', 15 | headers: { 16 | 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8' 17 | }, 18 | data: $httpParamSerializerJQLike({ 19 | ip: ip, 20 | port: port 21 | }) 22 | }); 23 | }; 24 | }] 25 | ); 26 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/metricservice.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('MetricService', ['$http', function ($http) { 4 | 5 | this.queryAppSortedIdentities = function (params) { 6 | return $http({ 7 | url: '/metric/queryTopResourceMetric.json', 8 | params: params, 9 | method: 'GET' 10 | }); 11 | }; 12 | 13 | this.queryByAppAndIdentity = function (params) { 14 | return $http({ 15 | url: '/metric/queryByAppAndResource.json', 16 | params: params, 17 | method: 'GET' 18 | }); 19 | }; 20 | 21 | this.queryByMachineAndIdentity = function (ip, port, identity, startTime, endTime) { 22 | var param = { 23 | ip: ip, 24 | port: port, 25 | identity: identity, 26 | startTime: startTime.getTime(), 27 | endTime: endTime.getTime() 28 | }; 29 | 30 | return $http({ 31 | url: '/metric/queryByAppAndResource.json', 32 | params: param, 33 | method: 'GET' 34 | }); 35 | }; 36 | }]); 37 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/scripts/services/systemservice.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('sentinelDashboardApp'); 2 | 3 | app.service('SystemService', ['$http', function ($http) { 4 | this.queryMachineRules = function (app, ip, port) { 5 | var param = { 6 | app: app, 7 | ip: ip, 8 | port: port 9 | }; 10 | return $http({ 11 | url: 'system/rules.json', 12 | params: param, 13 | method: 'GET' 14 | }); 15 | }; 16 | 17 | this.newRule = function (rule) { 18 | var param = { 19 | app: rule.app, 20 | ip: rule.ip, 21 | port: rule.port 22 | }; 23 | if (rule.grade == 0) {// avgLoad 24 | param.highestSystemLoad = rule.highestSystemLoad; 25 | } else if (rule.grade == 1) {// avgRt 26 | param.avgRt = rule.avgRt; 27 | } else if (rule.grade == 2) {// maxThread 28 | param.maxThread = rule.maxThread; 29 | } else if (rule.grade == 3) {// qps 30 | param.qps = rule.qps; 31 | } else if (rule.grade == 4) {// cpu 32 | param.highestCpuUsage = rule.highestCpuUsage; 33 | } 34 | 35 | return $http({ 36 | url: '/system/new.json', 37 | params: param, 38 | method: 'GET' 39 | }); 40 | }; 41 | 42 | this.saveRule = function (rule) { 43 | var param = { 44 | id: rule.id, 45 | }; 46 | if (rule.grade == 0) {// avgLoad 47 | param.highestSystemLoad = rule.highestSystemLoad; 48 | } else if (rule.grade == 1) {// avgRt 49 | param.avgRt = rule.avgRt; 50 | } else if (rule.grade == 2) {// maxThread 51 | param.maxThread = rule.maxThread; 52 | } else if (rule.grade == 3) {// qps 53 | param.qps = rule.qps; 54 | } else if (rule.grade == 4) {// cpu 55 | param.highestCpuUsage = rule.highestCpuUsage; 56 | } 57 | 58 | return $http({ 59 | url: '/system/save.json', 60 | params: param, 61 | method: 'GET' 62 | }); 63 | }; 64 | 65 | this.deleteRule = function (rule) { 66 | var param = { 67 | id: rule.id, 68 | app: rule.app 69 | }; 70 | 71 | return $http({ 72 | url: '/system/delete.json', 73 | params: param, 74 | method: 'GET' 75 | }); 76 | }; 77 | }]); 78 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/cluster/client.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |

未连接

7 |

连接中

8 |

已连接

9 |
10 |
11 |
12 | 13 |
14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 |
30 |
-------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/cluster/server.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |

独立模式 (Alone)

7 |

嵌入模式 (Embedded)

8 |
9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 |
19 | 20 |
21 |
22 |
23 | 24 |
25 | 26 |
27 |
28 |
29 |
-------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/dashboard/home.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

欢迎使用 Sentinel 控制台

5 |
6 | 7 |
8 | 9 | 10 |
11 |
12 | 13 |
14 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/dashboard/main.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 |
7 |
8 |
9 | 10 |
11 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/dialog/authority-rule-dialog.html: -------------------------------------------------------------------------------- 1 |
2 | {{authorityRuleDialog.title}} 3 |
4 |
5 |
6 |
7 |
8 | 9 |
10 | 12 | 14 |
15 |
16 | 17 |
18 | 19 |
20 | 22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 |  白名单   30 |  黑名单 31 |
32 |
33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | 41 | 43 |
44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/dialog/cluster/cluster-client-config-dialog.html: -------------------------------------------------------------------------------- 1 |
2 | 修改 Token Client 配置 3 |
4 |
5 |
6 |
7 |
8 | 9 |
10 |

{{ccDialogData.clientId}}

11 |
12 |
13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | 21 |
22 | 23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 |
34 |
35 | 36 | 37 |
38 |
39 |
40 |
41 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/dialog/cluster/cluster-server-connection-detail-dialog.html: -------------------------------------------------------------------------------- 1 |
2 | 连接详情 3 |
4 |
5 |
6 |
7 |
8 | 9 |
10 |

{{connectionDetailDialogData.serverData.id}}

11 |
12 |
13 |
14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
命名空间连接数连接详情
{{cg.namespace}}{{cg.connectedCount}}{{generateConnectionSet(cg.connectionSet)}}
33 |
34 |
35 |
36 |
37 |
38 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/dialog/confirm-dialog.html: -------------------------------------------------------------------------------- 1 |
2 | {{confirmDialog.title}} 3 |
4 |
5 |
6 |

7 | {{confirmDialog.attentionTitle}}: 8 |
9 |
10 | {{confirmDialog.attention}} 11 |

12 |
13 |
14 |
15 | 16 | 17 |
18 |
19 |
20 |
21 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/dialog/gateway/api-dialog.html: -------------------------------------------------------------------------------- 1 |
2 | {{gatewayApiDialog.title}} 3 |
4 |
5 |
6 |
7 | 8 |
9 | 11 | 12 |
13 |
14 | 15 |
16 | 17 |
18 |
19 |  精确   20 |  前缀   21 |  正则   22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 | 31 |
32 |
33 | 34 |
35 | 38 |
39 |
40 |
41 |
42 | 43 | 44 | 46 |
47 |
48 |
49 |
50 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/login.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Sentinel Logo 5 | 6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 14 |
15 | 16 |
17 |
18 | 19 |
20 | 21 |
22 | 23 |
24 |
25 |
26 | 28 | 30 |
31 |
32 |
33 |
34 |
-------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/app/views/pagination.tpl.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/assets/img/sentinel-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustly/blog_vue_server/a57470e7f2042d909926d5f548d985e3fbcdf84f/sentinel-dashboard/src/main/webapp/resources/assets/img/sentinel-logo.png -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sentinel Dashboard 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/index_dev.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sentinel 控制台 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/lib/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustly/blog_vue_server/a57470e7f2042d909926d5f548d985e3fbcdf84f/sentinel-dashboard/src/main/webapp/resources/lib/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/lib/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustly/blog_vue_server/a57470e7f2042d909926d5f548d985e3fbcdf84f/sentinel-dashboard/src/main/webapp/resources/lib/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/lib/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustly/blog_vue_server/a57470e7f2042d909926d5f548d985e3fbcdf84f/sentinel-dashboard/src/main/webapp/resources/lib/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/lib/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustly/blog_vue_server/a57470e7f2042d909926d5f548d985e3fbcdf84f/sentinel-dashboard/src/main/webapp/resources/lib/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/lib/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustly/blog_vue_server/a57470e7f2042d909926d5f548d985e3fbcdf84f/sentinel-dashboard/src/main/webapp/resources/lib/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/license-stat.csv: -------------------------------------------------------------------------------- 1 | Type,Package,License 2 | npm,angular,MIT License 3 | npm,angular-animate,MIT License 4 | npm,angular-bootstrap,MIT License 5 | npm,angular-clipboard,MIT License 6 | npm,angular-cookies,MIT License 7 | npm,angular-date-time-input,MIT License 8 | npm,angular-loading-bar,MIT License 9 | npm,angular-mocks,MIT License 10 | npm,angular-resource,MIT License 11 | npm,angular-route,MIT License 12 | npm,angular-selectize2,MIT License 13 | npm,angular-table-resize,MIT License 14 | npm,angular-touch,MIT License 15 | npm,angular-ui-notification,MIT License 16 | npm,angular-ui-router,MIT License 17 | npm,angular-utils-pagination,MIT License 18 | npm,angularjs-bootstrap-datetimepicker,MIT License 19 | npm,bootstrap-switch,Apache License 2.0 20 | npm,bootstrap-tagsinput,MIT License 21 | npm,moment,MIT License 22 | npm,ng-dialog,MIT License 23 | npm,ng-tags-input,MIT License 24 | npm,oclazyload,MIT License 25 | npm,selectize,Apache License 2.0 26 | lib,jsTreeTable,MIT License -------------------------------------------------------------------------------- /sentinel-dashboard/src/main/webapp/resources/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sentinel-dashboard", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo no test case", 8 | "build": "gulp build", 9 | "start": "gulp" 10 | }, 11 | "author": "x-cold ", 12 | "license": "MIT", 13 | "dependencies": { 14 | "angular": "^1.4.8", 15 | "angular-animate": "^1.4.0", 16 | "angular-bootstrap": "^0.12.2", 17 | "angular-clipboard": "^1.6.2", 18 | "angular-cookies": "^1.4.0", 19 | "angular-date-time-input": "^1.2.1", 20 | "angular-loading-bar": "^0.9.0", 21 | "angular-mocks": "^1.4.0", 22 | "angular-resource": "^1.4.0", 23 | "angular-route": "^1.4.0", 24 | "angular-selectize2": "^v1.2.3", 25 | "angular-table-resize": "^2.0.1", 26 | "angular-touch": "^1.4.0", 27 | "angular-ui-notification": "^0.3.6", 28 | "angular-ui-router": "^1.0.18", 29 | "angular-utils-pagination": "^0.11.1", 30 | "angularjs-bootstrap-datetimepicker": "^1.1.4", 31 | "bootstrap-switch": "^3.3.4", 32 | "bootstrap-tagsinput": "~0.7.1", 33 | "moment": "^2.12.0", 34 | "ng-dialog": "^0.6.6", 35 | "ng-tags-input": "~3.0.0", 36 | "oclazyload": "^1.1.0", 37 | "selectize": "^0.12.1", 38 | "lodash": ">=4.17.11" 39 | }, 40 | "devDependencies": { 41 | "gulp": "^3.9.1", 42 | "gulp-clean": "^0.4.0", 43 | "gulp-concat": "^2.6.1", 44 | "gulp-connect": "^5.7.0", 45 | "gulp-csscomb": "^3.0.8", 46 | "gulp-cssmin": "^0.2.0", 47 | "gulp-jshint": "^2.1.0", 48 | "gulp-load-plugins": "^1.6.0", 49 | "gulp-serv": "0.0.1", 50 | "gulp-uglify": "^3.0.0", 51 | "jshint": "^2.10.2", 52 | "open": "^6.3.0", 53 | "source-map": "^0.7.3" 54 | } 55 | } 56 | --------------------------------------------------------------------------------