Skip to content

Commit

Permalink
实现 apollo 规则持久化
Browse files Browse the repository at this point in the history
  • Loading branch information
kiwiflydream committed Sep 22, 2019
1 parent c7b7e05 commit 9c2a6f1
Show file tree
Hide file tree
Showing 25 changed files with 782 additions and 244 deletions.
2 changes: 1 addition & 1 deletion sentinel-dashboard/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>1.2.0</version>
<scope>test</scope>
<!--<scope>test</scope>-->
</dependency>

<!--for Zookeeper rule publisher sample-->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* coder4j.cn
* Copyright (C) 2013-2019 All Rights Reserved.
*/
package com.alibaba.csp.sentinel.dashboard.config;

import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @author buhao
* @version ApolloConfig.java, v 0.1 2019-09-06 10:56 buhao
*/
@Configuration
public class ApolloConfig {

@Value("${apollo.portal.url}")
private String apolloPortalUrl;
@Value("${apollo.application.token}")
private String apolloApplicationToken;

@Bean
public ApolloOpenApiClient apolloOpenApiClient() {
return ApolloOpenApiClient.newBuilder()
.withPortalUrl(apolloPortalUrl)
.withToken(apolloApplicationToken)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,21 @@
*/
package com.alibaba.csp.sentinel.dashboard.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;

import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;

import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -45,6 +40,10 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
* @author Eric Zhao
* @since 0.2.1
Expand All @@ -58,8 +57,13 @@ public class AuthorityRuleController {
@Autowired
private SentinelApiClient sentinelApiClient;
@Autowired
private RuleRepository<AuthorityRuleEntity, Long> repository;

private InMemoryRuleRepositoryAdapter<AuthorityRuleEntity> repository;
@Autowired
@Qualifier("authorityRuleApolloProvider")
private DynamicRuleProvider<List<AuthorityRuleEntity>> ruleProvider;
@Autowired
@Qualifier("authorityRuleApolloPublisher")
private DynamicRulePublisher<List<AuthorityRuleEntity>> rulePublisher;
@Autowired
private AuthService<HttpServletRequest> authService;

Expand All @@ -73,14 +77,19 @@ public Result<List<AuthorityRuleEntity>> apiQueryAllRulesForMachine(HttpServletR
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app cannot be null or empty");
}
if (StringUtil.isEmpty(ip)) {
return Result.ofFail(-1, "ip cannot be null or empty");
}
if (port == null || port <= 0) {
return Result.ofFail(-1, "Invalid parameter: port");
}
// if (StringUtil.isEmpty(ip)) {
// return Result.ofFail(-1, "ip cannot be null or empty");
// }
// if (port == null || port <= 0) {
// return Result.ofFail(-1, "Invalid parameter: port");
// }
try {
List<AuthorityRuleEntity> rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);
List<AuthorityRuleEntity> rules = ruleProvider.getRules(app);
if (rules != null && !rules.isEmpty()) {
for (AuthorityRuleEntity entity : rules) {
entity.setApp(app);
}
}
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (Throwable throwable) {
Expand All @@ -96,12 +105,12 @@ private <R> Result<R> checkEntityInternal(AuthorityRuleEntity entity) {
if (StringUtil.isBlank(entity.getApp())) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isBlank(entity.getIp())) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (entity.getPort() == null || entity.getPort() <= 0) {
return Result.ofFail(-1, "port can't be null");
}
// if (StringUtil.isBlank(entity.getIp())) {
// return Result.ofFail(-1, "ip can't be null or empty");
// }
// if (entity.getPort() == null || entity.getPort() <= 0) {
// return Result.ofFail(-1, "port can't be null");
// }
if (entity.getRule() == null) {
return Result.ofFail(-1, "rule can't be null");
}
Expand All @@ -112,7 +121,7 @@ private <R> Result<R> checkEntityInternal(AuthorityRuleEntity entity) {
return Result.ofFail(-1, "limitApp should be valid");
}
if (entity.getStrategy() != RuleConstant.AUTHORITY_WHITE
&& entity.getStrategy() != RuleConstant.AUTHORITY_BLACK) {
&& entity.getStrategy() != RuleConstant.AUTHORITY_BLACK) {
return Result.ofFail(-1, "Unknown strategy (must be blacklist or whitelist)");
}
return null;
Expand All @@ -133,13 +142,11 @@ public Result<AuthorityRuleEntity> apiAddAuthorityRule(HttpServletRequest reques
entity.setGmtModified(date);
try {
entity = repository.save(entity);
publishRules(entity.getApp());
} catch (Throwable throwable) {
logger.error("Failed to add authority rule", throwable);
return Result.ofThrowable(-1, throwable);
}
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {
logger.info("Publish authority rules failed after rule add");
}
return Result.ofSuccess(entity);
}

Expand All @@ -162,16 +169,14 @@ public Result<AuthorityRuleEntity> apiUpdateParamFlowRule(HttpServletRequest req
entity.setGmtModified(date);
try {
entity = repository.save(entity);
publishRules(entity.getApp());
if (entity == null) {
return Result.ofFail(-1, "Failed to save authority rule");
}
} catch (Throwable throwable) {
logger.error("Failed to save authority rule", throwable);
return Result.ofThrowable(-1, throwable);
}
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {
logger.info("Publish authority rules failed after rule update");
}
return Result.ofSuccess(entity);
}

Expand All @@ -188,17 +193,15 @@ public Result<Long> apiDeleteRule(HttpServletRequest request, @PathVariable("id"
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
publishRules(oldEntity.getApp());
} catch (Exception e) {
return Result.ofFail(-1, e.getMessage());
}
if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {
logger.error("Publish authority rules failed after rule delete");
}
return Result.ofSuccess(id);
}

private boolean publishRules(String app, String ip, Integer port) {
List<AuthorityRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setAuthorityRuleOfMachine(app, ip, port, rules);
private void publishRules(String app) throws Exception {
List<AuthorityRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,30 @@
*/
package com.alibaba.csp.sentinel.dashboard.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;

import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemDegradeRuleStore;

import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
* @author leyou
*/
Expand All @@ -50,9 +49,15 @@ public class DegradeController {
private final Logger logger = LoggerFactory.getLogger(DegradeController.class);

@Autowired
private InMemDegradeRuleStore repository;
private InMemoryRuleRepositoryAdapter<DegradeRuleEntity> repository;
@Autowired
private SentinelApiClient sentinelApiClient;
@Autowired
@Qualifier("degradeRuleApolloProvider")
private DynamicRuleProvider<List<DegradeRuleEntity>> ruleProvider;
@Autowired
@Qualifier("degradeRuleApolloPublisher")
private DynamicRulePublisher<List<DegradeRuleEntity>> rulePublisher;

@Autowired
private AuthService<HttpServletRequest> authService;
Expand All @@ -73,7 +78,12 @@ public Result<List<DegradeRuleEntity>> queryMachineRules(HttpServletRequest requ
return Result.ofFail(-1, "port can't be null");
}
try {
List<DegradeRuleEntity> rules = sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port);
List<DegradeRuleEntity> rules = ruleProvider.getRules(app);
if (rules != null && !rules.isEmpty()) {
for (DegradeRuleEntity entity : rules) {
entity.setApp(app);
}
}
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (Throwable throwable) {
Expand Down Expand Up @@ -131,13 +141,11 @@ public Result<DegradeRuleEntity> add(HttpServletRequest request,
entity.setGmtModified(date);
try {
entity = repository.save(entity);
publishRules(app);
} catch (Throwable throwable) {
logger.error("add error:", throwable);
return Result.ofThrowable(-1, throwable);
}
if (!publishRules(app, ip, port)) {
logger.info("publish degrade rules fail after rule add");
}
return Result.ofSuccess(entity);
}

Expand Down Expand Up @@ -183,13 +191,14 @@ public Result<DegradeRuleEntity> updateIfNotNull(HttpServletRequest request,
entity.setGmtModified(date);
try {
entity = repository.save(entity);
if (entity == null) {
return Result.ofFail(-1, "save entity fail");
}
publishRules(entity.getApp());
} catch (Throwable throwable) {
logger.error("save error:", throwable);
return Result.ofThrowable(-1, throwable);
}
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {
logger.info("publish degrade rules fail after rule update");
}
return Result.ofSuccess(entity);
}

Expand All @@ -208,18 +217,16 @@ public Result<Long> delete(HttpServletRequest request, Long id) {
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
publishRules(oldEntity.getApp());
} catch (Throwable throwable) {
logger.error("delete error:", throwable);
return Result.ofThrowable(-1, throwable);
}
if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {
logger.info("publish degrade rules fail after rule delete");
}
return Result.ofSuccess(id);
}

private boolean publishRules(String app, String ip, Integer port) {
List<DegradeRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setDegradeRuleOfMachine(app, ip, port, rules);
private void publishRules(String app) throws Exception {
List<DegradeRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
}
Loading

0 comments on commit 9c2a6f1

Please sign in to comment.