修改源码——同nacos类似

修改pom sentinel-dashboard项目注释pom.xml依赖(sentinel-datasource-nacos)作用域配置(test) 修改修改NacosConfig的配置 新增

/**

* 网关API

*

* @return

* @throws Exception

*/

@Bean

public Converter, String> apiDefinitionEntityEncoder() {

return JSON::toJSONString;

}

@Bean

public Converter> apiDefinitionEntityDecoder() {

return s -> JSON.parseArray(s, ApiDefinitionEntity.class);

}

/**

* 网关flowRule

*

* @return

* @throws Exception

*/

@Bean

public Converter, String> gatewayFlowRuleEntityEncoder() {

return JSON::toJSONString;

}

@Bean

public Converter> gatewayFlowRuleEntityDecoder() {

return s -> JSON.parseArray(s, GatewayFlowRuleEntity.class);

}

NacosConfigUtil文件中添加配置

public static final String GETWAY_FLOW_DATA_ID_POSTFIX = "-sentinel-gateway-flow-rules";

public static final String GETWAY_API_DATA_ID_POSTFIX = "-sentinel-gateway-api-rules";

创建GateWayFlowRulesNacosProvider、GateWayFlowRulesNacosPunlisher、GetWayApiNacosProvider、GetWayApiNacosPublisher文件

GateWayFlowRulesNacosProvider

package com.alibaba.csp.sentinel.dashboard.rule.gateway;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;

import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;

import com.alibaba.csp.sentinel.datasource.Converter;

import com.alibaba.csp.sentinel.util.StringUtil;

import com.alibaba.nacos.api.config.ConfigService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import java.util.ArrayList;

import java.util.List;

@Component("gateWayFlowRulesNacosProvider")

public class GateWayFlowRulesNacosProvider implements DynamicRuleProvider> {

@Autowired

private ConfigService configService;

@Autowired

private Converter> converter;

@Override

public List getRules(String appName) throws Exception {

String rules = configService.getConfig(appName + NacosConfigUtil.GETWAY_FLOW_DATA_ID_POSTFIX,

NacosConfigUtil.GROUP_ID, 3000);

if (StringUtil.isEmpty(rules)) {

return new ArrayList<>();

}

return converter.convert(rules);

}

}

GateWayFlowRulesNacosPunlisher

package com.alibaba.csp.sentinel.dashboard.rule.gateway;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;

import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;

import com.alibaba.csp.sentinel.datasource.Converter;

import com.alibaba.csp.sentinel.util.AssertUtil;

import com.alibaba.nacos.api.config.ConfigService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import java.util.List;

@Component("gateWayFlowRulesNacosPunlisher")

public class GateWayFlowRulesNacosPunlisher implements DynamicRulePublisher> {

@Autowired

private ConfigService configService;

@Autowired

private Converter, String> converter;

@Override

public void publish(String app, List rules) throws Exception {

AssertUtil.notEmpty(app, "app name cannot be empty");

if (rules == null) {

return;

}

configService.publishConfig(app + NacosConfigUtil.GETWAY_FLOW_DATA_ID_POSTFIX,

NacosConfigUtil.GROUP_ID, converter.convert(rules));

}

}

GetWayApiNacosProvider

package com.alibaba.csp.sentinel.dashboard.rule.gateway;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;

import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;

import com.alibaba.csp.sentinel.datasource.Converter;

import com.alibaba.csp.sentinel.util.StringUtil;

import com.alibaba.nacos.api.config.ConfigService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import java.util.ArrayList;

import java.util.List;

/**

* @author code

* @Date 2022/9/9 10:02

* Description gateway

* Version 1.0

*/

@Component("getWayApiNacosProvider")

public class GetWayApiNacosProvider implements DynamicRuleProvider> {

@Autowired

private ConfigService configService;

@Autowired

private Converter> converter;

@Override

public List getRules(String appName) throws Exception {

String rules = configService.getConfig(appName+ NacosConfigUtil.GETWAY_API_DATA_ID_POSTFIX

,NacosConfigUtil.GROUP_ID,3000);

if(StringUtil.isEmpty(rules)){

return new ArrayList<>();

}

return converter.convert(rules);

}

}

GetWayApiNacosPublisher

package com.alibaba.csp.sentinel.dashboard.rule.gateway;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;

import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;

import com.alibaba.csp.sentinel.datasource.Converter;

import com.alibaba.csp.sentinel.util.AssertUtil;

import com.alibaba.nacos.api.config.ConfigService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import java.util.List;

@Component("getWayApiNacosPublisher")

public class GetWayApiNacosPublisher implements DynamicRulePublisher> {

@Autowired

private ConfigService configService;

@Autowired

private Converter, String> converter;

@Override

public void publish(String app, List rules) throws Exception {

AssertUtil.notEmpty(app, "app name cannot be empty");

if (rules == null) {

return;

}

configService.publishConfig(app+ NacosConfigUtil.GETWAY_API_DATA_ID_POSTFIX,

NacosConfigUtil.GROUP_ID,converter.convert(rules));

}

}

修改controller

修改GatewayApiController 新增依赖注入

//添加我们自己写的ruleProvider

@Autowired

@Qualifier("getWayApiNacosProvider")

private DynamicRuleProvider> ruleProvider;

//添加我们自己写的 publisher

@Autowired

@Qualifier("getWayApiNacosPublisher")

private DynamicRulePublisher> rulePublisher;

修改queryApis方法,替换为拉取Nacos配置

// List apis = sentinelApiClient.fetchApis(app, ip, port).get();

List apis = ruleProvider.getRules(app);

新增方法

/**

* 把配置推给nacos中

*

* @param app

* @throws Exception

*/

private void publishApis(String app) {

List rules = repository.findAllByApp(app);

try {

rulePublisher.publish(app, rules);

} catch (Exception e) {

e.printStackTrace();

}

}

新增方法并全局替换掉旧方法,涉及替换的方法:addApi、updateApi、deleteApi 完成代码

/*

* Copyright 1999-2018 Alibaba Group Holding Ltd.

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.alibaba.csp.sentinel.dashboard.controller.gateway;

import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;

import com.alibaba.csp.sentinel.dashboard.auth.AuthService;

import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiPredicateItemEntity;

import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;

import com.alibaba.csp.sentinel.dashboard.domain.Result;

import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.AddApiReqVo;

import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.ApiPredicateItemVo;

import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.UpdateApiReqVo;

import com.alibaba.csp.sentinel.dashboard.repository.gateway.InMemApiDefinitionStore;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;

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.util.CollectionUtils;

import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

import java.util.*;

import static com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants.*;

/**

* Gateway api Controller for manage gateway api definitions.

*

* @author cdfive

* @since 1.7.0

*/

@RestController

@RequestMapping(value = "/gateway/api")

public class GatewayApiController {

private final Logger logger = LoggerFactory.getLogger(GatewayApiController.class);

@Autowired

private InMemApiDefinitionStore repository;

@Autowired

private SentinelApiClient sentinelApiClient;

//添加我们自己写的ruleProvider

@Autowired

@Qualifier("getWayApiNacosProvider")

private DynamicRuleProvider> ruleProvider;

//添加我们自己写的 publisher

@Autowired

@Qualifier("getWayApiNacosPublisher")

private DynamicRulePublisher> rulePublisher;

@GetMapping("/list.json")

@AuthAction(AuthService.PrivilegeType.READ_RULE)

public Result> queryApis(String app, String ip, Integer port) {

if (StringUtil.isEmpty(app)) {

return Result.ofFail(-1, "app can't be null or empty");

}

if (StringUtil.isEmpty(ip)) {

return Result.ofFail(-1, "ip can't be null or empty");

}

if (port == null) {

return Result.ofFail(-1, "port can't be null");

}

try {

// List apis = sentinelApiClient.fetchApis(app, ip, port).get();

List apis = ruleProvider.getRules(app);

repository.saveAll(apis);

return Result.ofSuccess(apis);

} catch (Throwable throwable) {

logger.error("queryApis error:", throwable);

return Result.ofThrowable(-1, throwable);

}

}

@PostMapping("/new.json")

@AuthAction(AuthService.PrivilegeType.WRITE_RULE)

public Result addApi(HttpServletRequest request, @RequestBody AddApiReqVo reqVo) {

String app = reqVo.getApp();

if (StringUtil.isBlank(app)) {

return Result.ofFail(-1, "app can't be null or empty");

}

ApiDefinitionEntity entity = new ApiDefinitionEntity();

entity.setApp(app.trim());

String ip = reqVo.getIp();

if (StringUtil.isBlank(ip)) {

return Result.ofFail(-1, "ip can't be null or empty");

}

entity.setIp(ip.trim());

Integer port = reqVo.getPort();

if (port == null) {

return Result.ofFail(-1, "port can't be null");

}

entity.setPort(port);

// API名称

String apiName = reqVo.getApiName();

if (StringUtil.isBlank(apiName)) {

return Result.ofFail(-1, "apiName can't be null or empty");

}

entity.setApiName(apiName.trim());

// 匹配规则列表

List predicateItems = reqVo.getPredicateItems();

if (CollectionUtils.isEmpty(predicateItems)) {

return Result.ofFail(-1, "predicateItems can't empty");

}

List predicateItemEntities = new ArrayList<>();

for (ApiPredicateItemVo predicateItem : predicateItems) {

ApiPredicateItemEntity predicateItemEntity = new ApiPredicateItemEntity();

// 匹配模式

Integer matchStrategy = predicateItem.getMatchStrategy();

if (!Arrays.asList(URL_MATCH_STRATEGY_EXACT, URL_MATCH_STRATEGY_PREFIX, URL_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {

return Result.ofFail(-1, "invalid matchStrategy: " + matchStrategy);

}

predicateItemEntity.setMatchStrategy(matchStrategy);

// 匹配串

String pattern = predicateItem.getPattern();

if (StringUtil.isBlank(pattern)) {

return Result.ofFail(-1, "pattern can't be null or empty");

}

predicateItemEntity.setPattern(pattern);

predicateItemEntities.add(predicateItemEntity);

}

entity.setPredicateItems(new LinkedHashSet<>(predicateItemEntities));

// 检查API名称不能重复

List allApis = repository.findAllByMachine(MachineInfo.of(app.trim(), ip.trim(), port));

if (allApis.stream().map(o -> o.getApiName()).anyMatch(o -> o.equals(apiName.trim()))) {

return Result.ofFail(-1, "apiName exists: " + apiName);

}

Date date = new Date();

entity.setGmtCreate(date);

entity.setGmtModified(date);

try {

entity = repository.save(entity);

} catch (Throwable throwable) {

logger.error("add gateway api error:", throwable);

return Result.ofThrowable(-1, throwable);

}

// if (!publishApis(app, ip, port)) {

// logger.warn("publish gateway apis fail after add");

// }

publishApis(app);

return Result.ofSuccess(entity);

}

@PostMapping("/save.json")

@AuthAction(AuthService.PrivilegeType.WRITE_RULE)

public Result updateApi(@RequestBody UpdateApiReqVo reqVo) {

String app = reqVo.getApp();

if (StringUtil.isBlank(app)) {

return Result.ofFail(-1, "app can't be null or empty");

}

Long id = reqVo.getId();

if (id == null) {

return Result.ofFail(-1, "id can't be null");

}

ApiDefinitionEntity entity = repository.findById(id);

if (entity == null) {

return Result.ofFail(-1, "api does not exist, id=" + id);

}

// 匹配规则列表

List predicateItems = reqVo.getPredicateItems();

if (CollectionUtils.isEmpty(predicateItems)) {

return Result.ofFail(-1, "predicateItems can't empty");

}

List predicateItemEntities = new ArrayList<>();

for (ApiPredicateItemVo predicateItem : predicateItems) {

ApiPredicateItemEntity predicateItemEntity = new ApiPredicateItemEntity();

// 匹配模式

int matchStrategy = predicateItem.getMatchStrategy();

if (!Arrays.asList(URL_MATCH_STRATEGY_EXACT, URL_MATCH_STRATEGY_PREFIX, URL_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {

return Result.ofFail(-1, "Invalid matchStrategy: " + matchStrategy);

}

predicateItemEntity.setMatchStrategy(matchStrategy);

// 匹配串

String pattern = predicateItem.getPattern();

if (StringUtil.isBlank(pattern)) {

return Result.ofFail(-1, "pattern can't be null or empty");

}

predicateItemEntity.setPattern(pattern);

predicateItemEntities.add(predicateItemEntity);

}

entity.setPredicateItems(new LinkedHashSet<>(predicateItemEntities));

Date date = new Date();

entity.setGmtModified(date);

try {

entity = repository.save(entity);

} catch (Throwable throwable) {

logger.error("update gateway api error:", throwable);

return Result.ofThrowable(-1, throwable);

}

// if (!publishApis(app, entity.getIp(), entity.getPort())) {

// logger.warn("publish gateway apis fail after update");

// }

publishApis(app);

return Result.ofSuccess(entity);

}

@PostMapping("/delete.json")

@AuthAction(AuthService.PrivilegeType.DELETE_RULE)

public Result deleteApi(Long id) {

if (id == null) {

return Result.ofFail(-1, "id can't be null");

}

ApiDefinitionEntity oldEntity = repository.findById(id);

if (oldEntity == null) {

return Result.ofSuccess(null);

}

try {

repository.delete(id);

} catch (Throwable throwable) {

logger.error("delete gateway api error:", throwable);

return Result.ofThrowable(-1, throwable);

}

// if (!publishApis(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {

// logger.warn("publish gateway apis fail after delete");

// }

publishApis(oldEntity.getApp());

return Result.ofSuccess(id);

}

private boolean publishApis(String app, String ip, Integer port) {

List apis = repository.findAllByMachine(MachineInfo.of(app, ip, port));

return sentinelApiClient.modifyApis(app, ip, port, apis);

}

/**

* 把配置推给nacos中

*

* @param app

* @throws Exception

*/

private void publishApis(String app) {

List rules = repository.findAllByApp(app);

try {

rulePublisher.publish(app, rules);

} catch (Exception e) {

e.printStackTrace();

}

}

}

修改GatewayFlowRuleController,同上

/*

* Copyright 1999-2018 Alibaba Group Holding Ltd.

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.alibaba.csp.sentinel.dashboard.controller.gateway;

import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;

import com.alibaba.csp.sentinel.dashboard.auth.AuthService;

import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayParamFlowItemEntity;

import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;

import com.alibaba.csp.sentinel.dashboard.domain.Result;

import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.rule.AddFlowRuleReqVo;

import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.rule.GatewayParamFlowItemVo;

import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.rule.UpdateFlowRuleReqVo;

import com.alibaba.csp.sentinel.dashboard.repository.gateway.InMemGatewayFlowRuleStore;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;

import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;

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.*;

import java.util.Arrays;

import java.util.Date;

import java.util.List;

import static com.alibaba.csp.sentinel.slots.block.RuleConstant.*;

import static com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants.*;

import static com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity.*;

/**

* Gateway flow rule Controller for manage gateway flow rules.

*

* @author cdfive

* @since 1.7.0

*/

@RestController

@RequestMapping(value = "/gateway/flow")

public class GatewayFlowRuleController {

private final Logger logger = LoggerFactory.getLogger(GatewayFlowRuleController.class);

@Autowired

private InMemGatewayFlowRuleStore repository;

@Autowired

private SentinelApiClient sentinelApiClient;

//添加我们自己写的ruleProvider

@Autowired

@Qualifier("gateWayFlowRulesNacosProvider")

private DynamicRuleProvider> ruleProvider;

//添加我们自己写的 publisher

@Autowired

@Qualifier("gateWayFlowRulesNacosPunlisher")

private DynamicRulePublisher> rulePublisher;

@GetMapping("/list.json")

@AuthAction(AuthService.PrivilegeType.READ_RULE)

public Result> queryFlowRules(String app, String ip, Integer port) {

if (StringUtil.isEmpty(app)) {

return Result.ofFail(-1, "app can't be null or empty");

}

if (StringUtil.isEmpty(ip)) {

return Result.ofFail(-1, "ip can't be null or empty");

}

if (port == null) {

return Result.ofFail(-1, "port can't be null");

}

try {

// List rules = sentinelApiClient.fetchGatewayFlowRules(app, ip, port).get();

List rules = ruleProvider.getRules(app);

repository.saveAll(rules);

return Result.ofSuccess(rules);

} catch (Throwable throwable) {

logger.error("query gateway flow rules error:", throwable);

return Result.ofThrowable(-1, throwable);

}

}

@PostMapping("/new.json")

@AuthAction(AuthService.PrivilegeType.WRITE_RULE)

public Result addFlowRule(@RequestBody AddFlowRuleReqVo reqVo) {

String app = reqVo.getApp();

if (StringUtil.isBlank(app)) {

return Result.ofFail(-1, "app can't be null or empty");

}

GatewayFlowRuleEntity entity = new GatewayFlowRuleEntity();

entity.setApp(app.trim());

String ip = reqVo.getIp();

if (StringUtil.isBlank(ip)) {

return Result.ofFail(-1, "ip can't be null or empty");

}

entity.setIp(ip.trim());

Integer port = reqVo.getPort();

if (port == null) {

return Result.ofFail(-1, "port can't be null");

}

entity.setPort(port);

// API类型, Route ID或API分组

Integer resourceMode = reqVo.getResourceMode();

if (resourceMode == null) {

return Result.ofFail(-1, "resourceMode can't be null");

}

if (!Arrays.asList(RESOURCE_MODE_ROUTE_ID, RESOURCE_MODE_CUSTOM_API_NAME).contains(resourceMode)) {

return Result.ofFail(-1, "invalid resourceMode: " + resourceMode);

}

entity.setResourceMode(resourceMode);

// API名称

String resource = reqVo.getResource();

if (StringUtil.isBlank(resource)) {

return Result.ofFail(-1, "resource can't be null or empty");

}

entity.setResource(resource.trim());

// 针对请求属性

GatewayParamFlowItemVo paramItem = reqVo.getParamItem();

if (paramItem != null) {

GatewayParamFlowItemEntity itemEntity = new GatewayParamFlowItemEntity();

entity.setParamItem(itemEntity);

// 参数属性 0-ClientIP 1-Remote Host 2-Header 3-URL参数 4-Cookie

Integer parseStrategy = paramItem.getParseStrategy();

if (!Arrays.asList(PARAM_PARSE_STRATEGY_CLIENT_IP, PARAM_PARSE_STRATEGY_HOST, PARAM_PARSE_STRATEGY_HEADER

, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {

return Result.ofFail(-1, "invalid parseStrategy: " + parseStrategy);

}

itemEntity.setParseStrategy(paramItem.getParseStrategy());

// 当参数属性为2-Header 3-URL参数 4-Cookie时,参数名称必填

if (Arrays.asList(PARAM_PARSE_STRATEGY_HEADER, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {

// 参数名称

String fieldName = paramItem.getFieldName();

if (StringUtil.isBlank(fieldName)) {

return Result.ofFail(-1, "fieldName can't be null or empty");

}

itemEntity.setFieldName(paramItem.getFieldName());

}

String pattern = paramItem.getPattern();

// 如果匹配串不为空,验证匹配模式

if (StringUtil.isNotEmpty(pattern)) {

itemEntity.setPattern(pattern);

Integer matchStrategy = paramItem.getMatchStrategy();

if (!Arrays.asList(PARAM_MATCH_STRATEGY_EXACT, PARAM_MATCH_STRATEGY_CONTAINS, PARAM_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {

return Result.ofFail(-1, "invalid matchStrategy: " + matchStrategy);

}

itemEntity.setMatchStrategy(matchStrategy);

}

}

// 阈值类型 0-线程数 1-QPS

Integer grade = reqVo.getGrade();

if (grade == null) {

return Result.ofFail(-1, "grade can't be null");

}

if (!Arrays.asList(FLOW_GRADE_THREAD, FLOW_GRADE_QPS).contains(grade)) {

return Result.ofFail(-1, "invalid grade: " + grade);

}

entity.setGrade(grade);

// QPS阈值

Double count = reqVo.getCount();

if (count == null) {

return Result.ofFail(-1, "count can't be null");

}

if (count < 0) {

return Result.ofFail(-1, "count should be at lease zero");

}

entity.setCount(count);

// 间隔

Long interval = reqVo.getInterval();

if (interval == null) {

return Result.ofFail(-1, "interval can't be null");

}

if (interval <= 0) {

return Result.ofFail(-1, "interval should be greater than zero");

}

entity.setInterval(interval);

// 间隔单位

Integer intervalUnit = reqVo.getIntervalUnit();

if (intervalUnit == null) {

return Result.ofFail(-1, "intervalUnit can't be null");

}

if (!Arrays.asList(INTERVAL_UNIT_SECOND, INTERVAL_UNIT_MINUTE, INTERVAL_UNIT_HOUR, INTERVAL_UNIT_DAY).contains(intervalUnit)) {

return Result.ofFail(-1, "Invalid intervalUnit: " + intervalUnit);

}

entity.setIntervalUnit(intervalUnit);

// 流控方式 0-快速失败 2-匀速排队

Integer controlBehavior = reqVo.getControlBehavior();

if (controlBehavior == null) {

return Result.ofFail(-1, "controlBehavior can't be null");

}

if (!Arrays.asList(CONTROL_BEHAVIOR_DEFAULT, CONTROL_BEHAVIOR_RATE_LIMITER).contains(controlBehavior)) {

return Result.ofFail(-1, "invalid controlBehavior: " + controlBehavior);

}

entity.setControlBehavior(controlBehavior);

if (CONTROL_BEHAVIOR_DEFAULT == controlBehavior) {

// 0-快速失败, 则Burst size必填

Integer burst = reqVo.getBurst();

if (burst == null) {

return Result.ofFail(-1, "burst can't be null");

}

if (burst < 0) {

return Result.ofFail(-1, "invalid burst: " + burst);

}

entity.setBurst(burst);

} else if (CONTROL_BEHAVIOR_RATE_LIMITER == controlBehavior) {

// 1-匀速排队, 则超时时间必填

Integer maxQueueingTimeoutMs = reqVo.getMaxQueueingTimeoutMs();

if (maxQueueingTimeoutMs == null) {

return Result.ofFail(-1, "maxQueueingTimeoutMs can't be null");

}

if (maxQueueingTimeoutMs < 0) {

return Result.ofFail(-1, "invalid maxQueueingTimeoutMs: " + maxQueueingTimeoutMs);

}

entity.setMaxQueueingTimeoutMs(maxQueueingTimeoutMs);

}

Date date = new Date();

entity.setGmtCreate(date);

entity.setGmtModified(date);

try {

entity = repository.save(entity);

} catch (Throwable throwable) {

logger.error("add gateway flow rule error:", throwable);

return Result.ofThrowable(-1, throwable);

}

// if (!publishRules(app, ip, port)) {

// logger.warn("publish gateway flow rules fail after add");

// }

publishRules(app);

return Result.ofSuccess(entity);

}

@PostMapping("/save.json")

@AuthAction(AuthService.PrivilegeType.WRITE_RULE)

public Result updateFlowRule(@RequestBody UpdateFlowRuleReqVo reqVo) {

String app = reqVo.getApp();

if (StringUtil.isBlank(app)) {

return Result.ofFail(-1, "app can't be null or empty");

}

Long id = reqVo.getId();

if (id == null) {

return Result.ofFail(-1, "id can't be null");

}

GatewayFlowRuleEntity entity = repository.findById(id);

if (entity == null) {

return Result.ofFail(-1, "gateway flow rule does not exist, id=" + id);

}

// 针对请求属性

GatewayParamFlowItemVo paramItem = reqVo.getParamItem();

if (paramItem != null) {

GatewayParamFlowItemEntity itemEntity = new GatewayParamFlowItemEntity();

entity.setParamItem(itemEntity);

// 参数属性 0-ClientIP 1-Remote Host 2-Header 3-URL参数 4-Cookie

Integer parseStrategy = paramItem.getParseStrategy();

if (!Arrays.asList(PARAM_PARSE_STRATEGY_CLIENT_IP, PARAM_PARSE_STRATEGY_HOST, PARAM_PARSE_STRATEGY_HEADER

, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {

return Result.ofFail(-1, "invalid parseStrategy: " + parseStrategy);

}

itemEntity.setParseStrategy(paramItem.getParseStrategy());

// 当参数属性为2-Header 3-URL参数 4-Cookie时,参数名称必填

if (Arrays.asList(PARAM_PARSE_STRATEGY_HEADER, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {

// 参数名称

String fieldName = paramItem.getFieldName();

if (StringUtil.isBlank(fieldName)) {

return Result.ofFail(-1, "fieldName can't be null or empty");

}

itemEntity.setFieldName(paramItem.getFieldName());

}

String pattern = paramItem.getPattern();

// 如果匹配串不为空,验证匹配模式

if (StringUtil.isNotEmpty(pattern)) {

itemEntity.setPattern(pattern);

Integer matchStrategy = paramItem.getMatchStrategy();

if (!Arrays.asList(PARAM_MATCH_STRATEGY_EXACT, PARAM_MATCH_STRATEGY_CONTAINS, PARAM_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {

return Result.ofFail(-1, "invalid matchStrategy: " + matchStrategy);

}

itemEntity.setMatchStrategy(matchStrategy);

}

} else {

entity.setParamItem(null);

}

// 阈值类型 0-线程数 1-QPS

Integer grade = reqVo.getGrade();

if (grade == null) {

return Result.ofFail(-1, "grade can't be null");

}

if (!Arrays.asList(FLOW_GRADE_THREAD, FLOW_GRADE_QPS).contains(grade)) {

return Result.ofFail(-1, "invalid grade: " + grade);

}

entity.setGrade(grade);

// QPS阈值

Double count = reqVo.getCount();

if (count == null) {

return Result.ofFail(-1, "count can't be null");

}

if (count < 0) {

return Result.ofFail(-1, "count should be at lease zero");

}

entity.setCount(count);

// 间隔

Long interval = reqVo.getInterval();

if (interval == null) {

return Result.ofFail(-1, "interval can't be null");

}

if (interval <= 0) {

return Result.ofFail(-1, "interval should be greater than zero");

}

entity.setInterval(interval);

// 间隔单位

Integer intervalUnit = reqVo.getIntervalUnit();

if (intervalUnit == null) {

return Result.ofFail(-1, "intervalUnit can't be null");

}

if (!Arrays.asList(INTERVAL_UNIT_SECOND, INTERVAL_UNIT_MINUTE, INTERVAL_UNIT_HOUR, INTERVAL_UNIT_DAY).contains(intervalUnit)) {

return Result.ofFail(-1, "Invalid intervalUnit: " + intervalUnit);

}

entity.setIntervalUnit(intervalUnit);

// 流控方式 0-快速失败 2-匀速排队

Integer controlBehavior = reqVo.getControlBehavior();

if (controlBehavior == null) {

return Result.ofFail(-1, "controlBehavior can't be null");

}

if (!Arrays.asList(CONTROL_BEHAVIOR_DEFAULT, CONTROL_BEHAVIOR_RATE_LIMITER).contains(controlBehavior)) {

return Result.ofFail(-1, "invalid controlBehavior: " + controlBehavior);

}

entity.setControlBehavior(controlBehavior);

if (CONTROL_BEHAVIOR_DEFAULT == controlBehavior) {

// 0-快速失败, 则Burst size必填

Integer burst = reqVo.getBurst();

if (burst == null) {

return Result.ofFail(-1, "burst can't be null");

}

if (burst < 0) {

return Result.ofFail(-1, "invalid burst: " + burst);

}

entity.setBurst(burst);

} else if (CONTROL_BEHAVIOR_RATE_LIMITER == controlBehavior) {

// 2-匀速排队, 则超时时间必填

Integer maxQueueingTimeoutMs = reqVo.getMaxQueueingTimeoutMs();

if (maxQueueingTimeoutMs == null) {

return Result.ofFail(-1, "maxQueueingTimeoutMs can't be null");

}

if (maxQueueingTimeoutMs < 0) {

return Result.ofFail(-1, "invalid maxQueueingTimeoutMs: " + maxQueueingTimeoutMs);

}

entity.setMaxQueueingTimeoutMs(maxQueueingTimeoutMs);

}

Date date = new Date();

entity.setGmtModified(date);

try {

entity = repository.save(entity);

} catch (Throwable throwable) {

logger.error("update gateway flow rule error:", throwable);

return Result.ofThrowable(-1, throwable);

}

// if (!publishRules(app, entity.getIp(), entity.getPort())) {

// logger.warn("publish gateway flow rules fail after update");

// }

publishRules(app);

return Result.ofSuccess(entity);

}

@PostMapping("/delete.json")

@AuthAction(AuthService.PrivilegeType.DELETE_RULE)

public Result deleteFlowRule(Long id) {

if (id == null) {

return Result.ofFail(-1, "id can't be null");

}

GatewayFlowRuleEntity oldEntity = repository.findById(id);

if (oldEntity == null) {

return Result.ofSuccess(null);

}

try {

repository.delete(id);

} catch (Throwable throwable) {

logger.error("delete gateway flow rule error:", throwable);

return Result.ofThrowable(-1, throwable);

}

// if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {

// logger.warn("publish gateway flow rules fail after delete");

// }

publishRules(oldEntity.getApp());

return Result.ofSuccess(id);

}

private boolean publishRules(String app, String ip, Integer port) {

List rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));

return sentinelApiClient.modifyGatewayFlowRules(app, ip, port, rules);

}

/**

* 把配置推给nacos中

*

* @param app

* @throws Exception

*/

private boolean publishRules(String app) {

List rules = repository.findAllByApp(app);

try {

rulePublisher.publish(app, rules);

} catch (Exception e) {

e.printStackTrace();

}

return true;

}

}

package

资源包:sentinel-dashboard-1.8.5.jar

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: