----初始化项目
This commit is contained in:
43
plugin/control/pom.xml
Normal file
43
plugin/control/pom.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2020 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>nacos-plugin</artifactId>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>nacos-control-plugin</artifactId>
|
||||
<name>nacos-control-plugin ${project.version}</name>
|
||||
<url>https://nacos.io</url>
|
||||
<description>Nacos control plugin pom.xml file</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control;
|
||||
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.control.configs.ControlConfigs;
|
||||
import com.alibaba.nacos.plugin.control.connection.ConnectionControlManager;
|
||||
import com.alibaba.nacos.plugin.control.connection.DefaultConnectionControlManager;
|
||||
import com.alibaba.nacos.plugin.control.event.ConnectionLimitRuleChangeEvent;
|
||||
import com.alibaba.nacos.plugin.control.event.TpsControlRuleChangeEvent;
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.RuleStorageProxy;
|
||||
import com.alibaba.nacos.plugin.control.spi.ControlManagerBuilder;
|
||||
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
|
||||
import com.alibaba.nacos.plugin.control.tps.DefaultTpsControlManager;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* control manager center.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class ControlManagerCenter {
|
||||
|
||||
static volatile ControlManagerCenter instance = null;
|
||||
|
||||
private final RuleStorageProxy ruleStorageProxy;
|
||||
|
||||
private TpsControlManager tpsControlManager;
|
||||
|
||||
private ConnectionControlManager connectionControlManager;
|
||||
|
||||
private ControlManagerCenter() {
|
||||
ruleStorageProxy = RuleStorageProxy.getInstance();
|
||||
Optional<ControlManagerBuilder> controlManagerBuilder = findTargetControlManagerBuilder();
|
||||
if (controlManagerBuilder.isPresent()) {
|
||||
initConnectionManager(controlManagerBuilder.get());
|
||||
initTpsControlManager(controlManagerBuilder.get());
|
||||
} else {
|
||||
buildNoLimitControlManagers();
|
||||
}
|
||||
}
|
||||
|
||||
private void initConnectionManager(ControlManagerBuilder controlManagerBuilder) {
|
||||
try {
|
||||
connectionControlManager = controlManagerBuilder.buildConnectionControlManager();
|
||||
Loggers.CONTROL.info("Build connection control manager, class={}",
|
||||
connectionControlManager.getClass().getCanonicalName());
|
||||
} catch (Exception e) {
|
||||
Loggers.CONTROL.warn("Build connection control manager failed, use no limit manager replaced.", e);
|
||||
connectionControlManager = new DefaultConnectionControlManager();
|
||||
}
|
||||
}
|
||||
|
||||
private void initTpsControlManager(ControlManagerBuilder controlManagerBuilder) {
|
||||
try {
|
||||
tpsControlManager = controlManagerBuilder.buildTpsControlManager();
|
||||
Loggers.CONTROL
|
||||
.info("Build tps control manager, class={}", tpsControlManager.getClass().getCanonicalName());
|
||||
} catch (Exception e) {
|
||||
Loggers.CONTROL.warn("Build tps control manager failed, use no limit manager replaced.", e);
|
||||
tpsControlManager = new DefaultTpsControlManager();
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<ControlManagerBuilder> findTargetControlManagerBuilder() {
|
||||
String controlManagerType = ControlConfigs.getInstance().getControlManagerType();
|
||||
if (StringUtils.isEmpty(controlManagerType)) {
|
||||
Loggers.CONTROL.info("Not configure type of control plugin, no limit control for current node.");
|
||||
return Optional.empty();
|
||||
}
|
||||
for (ControlManagerBuilder each : NacosServiceLoader.load(ControlManagerBuilder.class)) {
|
||||
Loggers.CONTROL.info("Found control manager plugin of name={}", each.getName());
|
||||
if (controlManagerType.equalsIgnoreCase(each.getName())) {
|
||||
return Optional.of(each);
|
||||
}
|
||||
}
|
||||
Loggers.CONTROL.warn("Not found control manager plugin of name");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void buildNoLimitControlManagers() {
|
||||
connectionControlManager = new DefaultConnectionControlManager();
|
||||
tpsControlManager = new DefaultTpsControlManager();
|
||||
}
|
||||
|
||||
public RuleStorageProxy getRuleStorageProxy() {
|
||||
return ruleStorageProxy;
|
||||
}
|
||||
|
||||
public TpsControlManager getTpsControlManager() {
|
||||
return tpsControlManager;
|
||||
}
|
||||
|
||||
public ConnectionControlManager getConnectionControlManager() {
|
||||
return connectionControlManager;
|
||||
}
|
||||
|
||||
public static ControlManagerCenter getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (ControlManagerCenter.class) {
|
||||
if (instance == null) {
|
||||
instance = new ControlManagerCenter();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void reloadTpsControlRule(String pointName, boolean external) {
|
||||
NotifyCenter.publishEvent(new TpsControlRuleChangeEvent(pointName, external));
|
||||
}
|
||||
|
||||
public void reloadConnectionControlRule(boolean external) {
|
||||
NotifyCenter.publishEvent(new ConnectionLimitRuleChangeEvent(external));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* cotrol loggers.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class Loggers {
|
||||
|
||||
public static final Logger CONTROL = LoggerFactory.getLogger("com.alibaba.nacos.plugin.control");
|
||||
|
||||
public static final Logger TPS = LoggerFactory.getLogger("com.alibaba.nacos.plugin.control.tps");
|
||||
|
||||
public static final Logger CONNECTION = LoggerFactory.getLogger("com.alibaba.nacos.plugin.control.connection");
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.configs;
|
||||
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* control configs params.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class ControlConfigs {
|
||||
|
||||
private static volatile ControlConfigs instance = null;
|
||||
|
||||
public static ControlConfigs getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (ControlConfigs.class) {
|
||||
if (instance == null) {
|
||||
instance = new ControlConfigs();
|
||||
Collection<ControlConfigsInitializer> load = NacosServiceLoader
|
||||
.load(ControlConfigsInitializer.class);
|
||||
for (ControlConfigsInitializer controlConfigsInitializer : load) {
|
||||
controlConfigsInitializer.initialize(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void setInstance(ControlConfigs instance) {
|
||||
ControlConfigs.instance = instance;
|
||||
}
|
||||
|
||||
private String connectionRuntimeEjector = "nacos";
|
||||
|
||||
private String ruleExternalStorage = "";
|
||||
|
||||
private String localRuleStorageBaseDir = "";
|
||||
|
||||
private String controlManagerType = "";
|
||||
|
||||
public String getRuleExternalStorage() {
|
||||
return ruleExternalStorage;
|
||||
}
|
||||
|
||||
public void setRuleExternalStorage(String ruleExternalStorage) {
|
||||
this.ruleExternalStorage = ruleExternalStorage;
|
||||
}
|
||||
|
||||
public String getConnectionRuntimeEjector() {
|
||||
return connectionRuntimeEjector;
|
||||
}
|
||||
|
||||
public void setConnectionRuntimeEjector(String connectionRuntimeEjector) {
|
||||
this.connectionRuntimeEjector = connectionRuntimeEjector;
|
||||
}
|
||||
|
||||
public String getLocalRuleStorageBaseDir() {
|
||||
return localRuleStorageBaseDir;
|
||||
}
|
||||
|
||||
public void setLocalRuleStorageBaseDir(String localRuleStorageBaseDir) {
|
||||
this.localRuleStorageBaseDir = localRuleStorageBaseDir;
|
||||
}
|
||||
|
||||
public String getControlManagerType() {
|
||||
return controlManagerType;
|
||||
}
|
||||
|
||||
public void setControlManagerType(String controlManagerType) {
|
||||
this.controlManagerType = controlManagerType;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.configs;
|
||||
|
||||
/**
|
||||
* control plugin configs initializer.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public interface ControlConfigsInitializer {
|
||||
|
||||
/**
|
||||
* init control configs.
|
||||
*
|
||||
* @param controlConfigs control configs.
|
||||
*/
|
||||
void initialize(ControlConfigs controlConfigs);
|
||||
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection;
|
||||
|
||||
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.connection.request.ConnectionCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.connection.response.ConnectionCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
import com.alibaba.nacos.plugin.control.rule.parser.ConnectionControlRuleParser;
|
||||
import com.alibaba.nacos.plugin.control.rule.parser.NacosConnectionControlRuleParser;
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.RuleStorageProxy;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* connection control manager.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class ConnectionControlManager {
|
||||
|
||||
private final ConnectionControlRuleParser connectionControlRuleParser;
|
||||
|
||||
protected ConnectionControlRule connectionControlRule;
|
||||
|
||||
protected Collection<ConnectionMetricsCollector> metricsCollectorList;
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
public ConnectionControlManager() {
|
||||
metricsCollectorList = NacosServiceLoader.load(ConnectionMetricsCollector.class);
|
||||
Loggers.CONTROL.info("Load connection metrics collector,size={},{}", metricsCollectorList.size(),
|
||||
metricsCollectorList);
|
||||
this.connectionControlRuleParser = buildConnectionControlRuleParser();
|
||||
initConnectionRule();
|
||||
if (!metricsCollectorList.isEmpty()) {
|
||||
initExecuteService();
|
||||
startConnectionMetricsReport();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get manager name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
protected ConnectionControlRuleParser buildConnectionControlRuleParser() {
|
||||
return new NacosConnectionControlRuleParser();
|
||||
}
|
||||
|
||||
public ConnectionControlRuleParser getConnectionControlRuleParser() {
|
||||
return connectionControlRuleParser;
|
||||
}
|
||||
|
||||
private void initExecuteService() {
|
||||
executorService = ExecutorFactory.newSingleScheduledExecutorService(r -> {
|
||||
Thread thread = new Thread(r, "nacos.plugin.control.connection.reporter");
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
|
||||
private void initConnectionRule() {
|
||||
RuleStorageProxy ruleStorageProxy = RuleStorageProxy.getInstance();
|
||||
String localRuleContent = ruleStorageProxy.getLocalDiskStorage().getConnectionRule();
|
||||
if (StringUtils.isNotBlank(localRuleContent)) {
|
||||
Loggers.CONTROL.info("Found local disk connection rule content on start up,value ={}", localRuleContent);
|
||||
} else if (ruleStorageProxy.getExternalStorage() != null
|
||||
&& ruleStorageProxy.getExternalStorage().getConnectionRule() != null) {
|
||||
localRuleContent = ruleStorageProxy.getExternalStorage().getConnectionRule();
|
||||
if (StringUtils.isNotBlank(localRuleContent)) {
|
||||
Loggers.CONTROL.info("Found persist disk connection rule content on start up ,value ={}",
|
||||
localRuleContent);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(localRuleContent)) {
|
||||
connectionControlRule = connectionControlRuleParser.parseRule(localRuleContent);
|
||||
Loggers.CONTROL.info("init connection rule end");
|
||||
|
||||
} else {
|
||||
Loggers.CONTROL.info("No connection rule content found ,use default empty rule ");
|
||||
connectionControlRule = new ConnectionControlRule();
|
||||
}
|
||||
}
|
||||
|
||||
private void startConnectionMetricsReport() {
|
||||
executorService.scheduleWithFixedDelay(new ConnectionMetricsReporter(), 0, 3000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public ConnectionControlRule getConnectionLimitRule() {
|
||||
return connectionControlRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply connection rule.
|
||||
*
|
||||
* @param connectionControlRule not null.
|
||||
*/
|
||||
public abstract void applyConnectionLimitRule(ConnectionControlRule connectionControlRule);
|
||||
|
||||
/**
|
||||
* check connection allowed.
|
||||
*
|
||||
* @param connectionCheckRequest connectionCheckRequest.
|
||||
* @return
|
||||
*/
|
||||
public abstract ConnectionCheckResponse check(ConnectionCheckRequest connectionCheckRequest);
|
||||
|
||||
class ConnectionMetricsReporter implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Map<String, Integer> metricsTotalCount = metricsCollectorList.stream().collect(
|
||||
Collectors.toMap(ConnectionMetricsCollector::getName, ConnectionMetricsCollector::getTotalCount));
|
||||
int totalCount = metricsTotalCount.values().stream().mapToInt(Integer::intValue).sum();
|
||||
|
||||
Loggers.CONNECTION.info("ConnectionMetrics, totalCount = {}, detail = {}", totalCount, metricsTotalCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection;
|
||||
|
||||
/**
|
||||
* connection count metrics collector.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public interface ConnectionMetricsCollector {
|
||||
|
||||
/**
|
||||
* get collector name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* get total count.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getTotalCount();
|
||||
|
||||
/**
|
||||
* get count for ip.
|
||||
*
|
||||
* @param ip ip.
|
||||
* @return
|
||||
*/
|
||||
int getCountForIp(String ip);
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.connection;
|
||||
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.connection.request.ConnectionCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.connection.response.ConnectionCheckCode;
|
||||
import com.alibaba.nacos.plugin.control.connection.response.ConnectionCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
|
||||
/**
|
||||
* default connection control manager, no limit control.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class DefaultConnectionControlManager extends ConnectionControlManager {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "noLimit";
|
||||
}
|
||||
|
||||
public DefaultConnectionControlManager() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyConnectionLimitRule(ConnectionControlRule connectionControlRule) {
|
||||
super.connectionControlRule = connectionControlRule;
|
||||
Loggers.CONTROL.info("Connection control rule updated to -> {}",
|
||||
(this.connectionControlRule == null ? null : JacksonUtils.toJson(this.connectionControlRule)));
|
||||
Loggers.CONTROL.warn("Connection control updated, But connection control manager is no limit implementation.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionCheckResponse check(ConnectionCheckRequest connectionCheckRequest) {
|
||||
ConnectionCheckResponse connectionCheckResponse = new ConnectionCheckResponse();
|
||||
connectionCheckResponse.setSuccess(true);
|
||||
connectionCheckResponse.setCode(ConnectionCheckCode.CHECK_SKIP);
|
||||
return connectionCheckResponse;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection.request;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* connection check request.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class ConnectionCheckRequest {
|
||||
|
||||
String clientIp;
|
||||
|
||||
String appName;
|
||||
|
||||
String source;
|
||||
|
||||
Map<String, String> labels;
|
||||
|
||||
public ConnectionCheckRequest(String clientIp, String appName, String source) {
|
||||
this.appName = appName;
|
||||
this.clientIp = clientIp;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public Map<String, String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
public void setLabels(Map<String, String> labels) {
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
public String getClientIp() {
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
public void setClientIp(String clientIp) {
|
||||
this.clientIp = clientIp;
|
||||
}
|
||||
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection.response;
|
||||
|
||||
/**
|
||||
* connection check code.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class ConnectionCheckCode {
|
||||
|
||||
/**
|
||||
* check pass.
|
||||
*/
|
||||
public static final int PASS_BY_TOTAL = 200;
|
||||
|
||||
/**
|
||||
* skip.
|
||||
*/
|
||||
public static final int CHECK_SKIP = 100;
|
||||
|
||||
/**
|
||||
* deny by total over limit.
|
||||
*/
|
||||
public static final int DENY_BY_TOTAL_OVER = 300;
|
||||
|
||||
/**
|
||||
* pass by monitor type.
|
||||
*/
|
||||
public static final int PASS_BY_MONITOR = 205;
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection.response;
|
||||
|
||||
/**
|
||||
* connection check response.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class ConnectionCheckResponse {
|
||||
|
||||
private boolean success;
|
||||
|
||||
private String message;
|
||||
|
||||
private int code;
|
||||
|
||||
private String limitMessage;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getLimitMessage() {
|
||||
return limitMessage;
|
||||
}
|
||||
|
||||
public void setLimitMessage(String limitMessage) {
|
||||
this.limitMessage = limitMessage;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection.rule;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* connection control rule.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class ConnectionControlRule {
|
||||
|
||||
private Set<String> monitorIpList = new HashSet<>();
|
||||
|
||||
private int countLimit = -1;
|
||||
|
||||
public int getCountLimit() {
|
||||
return countLimit;
|
||||
}
|
||||
|
||||
public void setCountLimit(int countLimit) {
|
||||
this.countLimit = countLimit;
|
||||
}
|
||||
|
||||
public Set<String> getMonitorIpList() {
|
||||
return monitorIpList;
|
||||
}
|
||||
|
||||
public void setMonitorIpList(Set<String> monitorIpList) {
|
||||
this.monitorIpList = monitorIpList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.event;
|
||||
|
||||
import com.alibaba.nacos.common.notify.Event;
|
||||
|
||||
/**
|
||||
* connection limit rule change event.
|
||||
* @author zunfei.lzf
|
||||
*/
|
||||
public class ConnectionLimitRuleChangeEvent extends Event {
|
||||
|
||||
private boolean external;
|
||||
|
||||
public ConnectionLimitRuleChangeEvent(boolean external) {
|
||||
this.external = external;
|
||||
}
|
||||
|
||||
public boolean isExternal() {
|
||||
return external;
|
||||
}
|
||||
|
||||
public void setExternal(boolean external) {
|
||||
this.external = external;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.event;
|
||||
|
||||
import com.alibaba.nacos.common.notify.Event;
|
||||
|
||||
/**
|
||||
* tps control point.
|
||||
*
|
||||
* @author liuzunfei
|
||||
* @version $Id: TpsControlPoint.java, v 0.1 2021年01月09日 12:38 PM liuzunfei Exp $
|
||||
*/
|
||||
public class TpsControlRuleChangeEvent extends Event {
|
||||
|
||||
private String pointName;
|
||||
|
||||
private boolean external;
|
||||
|
||||
public TpsControlRuleChangeEvent(String pointName, boolean external) {
|
||||
this.pointName = pointName;
|
||||
this.external = external;
|
||||
}
|
||||
|
||||
public String getPointName() {
|
||||
return pointName;
|
||||
}
|
||||
|
||||
public void setPointName(String pointName) {
|
||||
this.pointName = pointName;
|
||||
}
|
||||
|
||||
public boolean isExternal() {
|
||||
return external;
|
||||
}
|
||||
|
||||
public void setExternal(boolean external) {
|
||||
this.external = external;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule;
|
||||
|
||||
import com.alibaba.nacos.common.notify.Event;
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.control.ControlManagerCenter;
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.connection.ConnectionControlManager;
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
import com.alibaba.nacos.plugin.control.event.ConnectionLimitRuleChangeEvent;
|
||||
import com.alibaba.nacos.plugin.control.event.TpsControlRuleChangeEvent;
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.RuleStorageProxy;
|
||||
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* control rule activator.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class ControlRuleChangeActivator {
|
||||
|
||||
private static final Logger LOGGER = Loggers.CONTROL;
|
||||
|
||||
TpsRuleChangeSubscriber tpsRuleChangeSubscriber = new TpsRuleChangeSubscriber();
|
||||
|
||||
ConnectionRuleChangeSubscriber connectionRuleChangeSubscriber = new ConnectionRuleChangeSubscriber();
|
||||
|
||||
public ControlRuleChangeActivator() {
|
||||
NotifyCenter.registerSubscriber(tpsRuleChangeSubscriber);
|
||||
NotifyCenter.registerSubscriber(connectionRuleChangeSubscriber);
|
||||
}
|
||||
|
||||
static class TpsRuleChangeSubscriber extends Subscriber<TpsControlRuleChangeEvent> {
|
||||
|
||||
@Override
|
||||
public void onEvent(TpsControlRuleChangeEvent event) {
|
||||
String pointName = event.getPointName();
|
||||
LOGGER.info("Tps control rule change event receive,pointName={}, external={} ", pointName,
|
||||
event.isExternal());
|
||||
if (event.getPointName() == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
RuleStorageProxy ruleStorageProxy = ControlManagerCenter.getInstance().getRuleStorageProxy();
|
||||
|
||||
if (event.isExternal()) {
|
||||
if (ruleStorageProxy.getExternalStorage() != null) {
|
||||
String persistTpsRule = ruleStorageProxy.getExternalStorage().getTpsRule(pointName);
|
||||
ruleStorageProxy.getLocalDiskStorage().saveTpsRule(pointName, persistTpsRule);
|
||||
} else {
|
||||
Loggers.CONTROL.info(
|
||||
"No external rule storage found,will load local disk instead,point name={}",
|
||||
event.getPointName());
|
||||
}
|
||||
|
||||
}
|
||||
String tpsRuleContent = ruleStorageProxy.getLocalDiskStorage().getTpsRule(pointName);
|
||||
TpsControlManager tpsControlManager = ControlManagerCenter.getInstance().getTpsControlManager();
|
||||
TpsControlRule tpsControlRule = StringUtils.isBlank(tpsRuleContent) ? new TpsControlRule()
|
||||
: tpsControlManager.getTpsControlRuleParser().parseRule(tpsRuleContent);
|
||||
|
||||
tpsControlManager.applyTpsRule(pointName, tpsControlRule);
|
||||
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Tps control rule apply error ,error= ", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Event> subscribeType() {
|
||||
return TpsControlRuleChangeEvent.class;
|
||||
}
|
||||
}
|
||||
|
||||
static class ConnectionRuleChangeSubscriber extends Subscriber<ConnectionLimitRuleChangeEvent> {
|
||||
|
||||
@Override
|
||||
public void onEvent(ConnectionLimitRuleChangeEvent event) {
|
||||
LOGGER.info("connection limit rule change event receive ,external:{}", event.isExternal());
|
||||
|
||||
try {
|
||||
|
||||
RuleStorageProxy ruleStorageProxy = ControlManagerCenter.getInstance().getRuleStorageProxy();
|
||||
|
||||
if (event.isExternal()) {
|
||||
if (ruleStorageProxy.getExternalStorage() != null) {
|
||||
String connectionRule = ruleStorageProxy.getExternalStorage().getConnectionRule();
|
||||
ruleStorageProxy.getLocalDiskStorage().saveConnectionRule(connectionRule);
|
||||
} else {
|
||||
Loggers.CONTROL.info("No external rule storage found,will load local disk instead");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
String limitRule = ruleStorageProxy.getLocalDiskStorage().getConnectionRule();
|
||||
|
||||
Loggers.CONTROL.info("start to apply connection rule content {}", limitRule);
|
||||
ConnectionControlManager controlManager = ControlManagerCenter.getInstance()
|
||||
.getConnectionControlManager();
|
||||
ConnectionControlRule connectionControlRule =
|
||||
StringUtils.isBlank(limitRule) ? new ConnectionControlRule()
|
||||
: controlManager.getConnectionControlRuleParser().parseRule(limitRule);
|
||||
Loggers.CONTROL.info("end to apply connection rule content ");
|
||||
|
||||
if (connectionControlRule != null) {
|
||||
controlManager.applyConnectionLimitRule(connectionControlRule);
|
||||
} else {
|
||||
LOGGER.info("Parse rule is null,Ignore illegal rule :{}", limitRule);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Fail to parse connection limit rule ,persit:{}", event.isExternal(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Event> subscribeType() {
|
||||
return ConnectionLimitRuleChangeEvent.class;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.parser;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
|
||||
/**
|
||||
* Connection control rule parser.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface ConnectionControlRuleParser extends RuleParser<ConnectionControlRule> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.parser;
|
||||
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
|
||||
/**
|
||||
* Nacos default connection control rule parser with json.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class NacosConnectionControlRuleParser implements ConnectionControlRuleParser {
|
||||
|
||||
@Override
|
||||
public ConnectionControlRule parseRule(String ruleContent) {
|
||||
return StringUtils.isBlank(ruleContent) ? new ConnectionControlRule()
|
||||
: JacksonUtils.toObj(ruleContent, ConnectionControlRule.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.parser;
|
||||
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
|
||||
/**
|
||||
* Nacos default tps control rule parser with json.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class NacosTpsControlRuleParser implements TpsControlRuleParser {
|
||||
|
||||
@Override
|
||||
public TpsControlRule parseRule(String ruleContent) {
|
||||
return StringUtils.isBlank(ruleContent) ? new TpsControlRule()
|
||||
: JacksonUtils.toObj(ruleContent, TpsControlRule.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.parser;
|
||||
|
||||
/**
|
||||
* parse rule content from raw string.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public interface RuleParser<R> {
|
||||
|
||||
/**
|
||||
* Parse control rule.
|
||||
*
|
||||
* @param ruleContent rule raw string
|
||||
* @return target rule
|
||||
*/
|
||||
R parseRule(String ruleContent);
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.parser;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
|
||||
/**
|
||||
* Tps control rule parser.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface TpsControlRuleParser extends RuleParser<TpsControlRule> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.storage;
|
||||
|
||||
/**
|
||||
* external rule storage.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public interface ExternalRuleStorage extends RuleStorage {
|
||||
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.storage;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.utils.DiskUtils;
|
||||
import com.alibaba.nacos.plugin.control.utils.EnvUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* local disk storage.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class LocalDiskRuleStorage implements RuleStorage {
|
||||
|
||||
LocalDiskRuleStorage() {
|
||||
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = Loggers.CONTROL;
|
||||
|
||||
private String localRuleBaseDir = defaultBaseDir();
|
||||
|
||||
private File checkTpsBaseDir() {
|
||||
File baseDir = new File(localRuleBaseDir, "data" + File.separator + "tps" + File.separator);
|
||||
if (!baseDir.exists()) {
|
||||
baseDir.mkdirs();
|
||||
}
|
||||
return baseDir;
|
||||
}
|
||||
|
||||
public void setLocalRuleBaseDir(String localRruleBaseDir) {
|
||||
this.localRuleBaseDir = localRruleBaseDir;
|
||||
}
|
||||
|
||||
private static String defaultBaseDir() {
|
||||
return EnvUtils.getNacosHome();
|
||||
}
|
||||
|
||||
private File getConnectionRuleFile() {
|
||||
File baseDir = new File(localRuleBaseDir, "data" + File.separator + "connection" + File.separator);
|
||||
if (!baseDir.exists()) {
|
||||
baseDir.mkdirs();
|
||||
}
|
||||
return new File(baseDir, "limitRule");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "localdisk";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConnectionRule(String ruleContent) throws IOException {
|
||||
File pointFile = getConnectionRuleFile();
|
||||
if (!pointFile.exists()) {
|
||||
pointFile.createNewFile();
|
||||
}
|
||||
DiskUtils.writeFile(pointFile, ruleContent.getBytes(Constants.ENCODE), false);
|
||||
LOGGER.info("Save connection rule to local, ruleContent ={} ", ruleContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionRule() {
|
||||
File connectionRuleFile = getConnectionRuleFile();
|
||||
if (!connectionRuleFile.exists()) {
|
||||
return null;
|
||||
}
|
||||
return DiskUtils.readFile(connectionRuleFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveTpsRule(String pointName, String ruleContent) throws IOException {
|
||||
File file = checkTpsBaseDir();
|
||||
File tpsFile = new File(file, pointName);
|
||||
if (!tpsFile.exists()) {
|
||||
tpsFile.createNewFile();
|
||||
}
|
||||
if (ruleContent == null) {
|
||||
DiskUtils.deleteQuietly(tpsFile);
|
||||
} else {
|
||||
DiskUtils.writeFile(tpsFile, ruleContent.getBytes(Constants.ENCODE), false);
|
||||
LOGGER.info("Save tps rule to local,pointName={}, ruleContent ={} ", pointName, ruleContent);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTpsRule(String pointName) {
|
||||
File file = checkTpsBaseDir();
|
||||
File tpsFile = new File(file, pointName);
|
||||
if (!tpsFile.exists()) {
|
||||
return null;
|
||||
}
|
||||
return DiskUtils.readFile(tpsFile);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.storage;
|
||||
|
||||
/**
|
||||
* rule storage.
|
||||
*
|
||||
* @author shiyiyue
|
||||
* @date 2022-10-26 11:43:00
|
||||
*/
|
||||
public interface RuleStorage {
|
||||
|
||||
/**
|
||||
* get storage name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* save connection rule to storage.
|
||||
*
|
||||
* @param ruleContent rule content.
|
||||
* @throws Exception exception.
|
||||
*/
|
||||
void saveConnectionRule(String ruleContent) throws Exception;
|
||||
|
||||
/**
|
||||
* get connection rule.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getConnectionRule();
|
||||
|
||||
/**
|
||||
* save tps rule.
|
||||
*
|
||||
* @param pointName point name.
|
||||
* @param ruleContent rule content.
|
||||
* @throws Exception exception.
|
||||
*/
|
||||
void saveTpsRule(String pointName, String ruleContent) throws Exception;
|
||||
|
||||
/**
|
||||
* get tps rule.
|
||||
*
|
||||
* @param pointName point name.
|
||||
* @return
|
||||
*/
|
||||
String getTpsRule(String pointName);
|
||||
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.rule.storage;
|
||||
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.configs.ControlConfigs;
|
||||
import com.alibaba.nacos.plugin.control.rule.ControlRuleChangeActivator;
|
||||
import com.alibaba.nacos.plugin.control.spi.ExternalRuleStorageBuilder;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* rule storage proxy.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class RuleStorageProxy {
|
||||
|
||||
private static final Logger LOGGER = Loggers.CONTROL;
|
||||
|
||||
private static final RuleStorageProxy INSTANCE = new RuleStorageProxy();
|
||||
|
||||
private LocalDiskRuleStorage localDiskRuleStorage = null;
|
||||
|
||||
private ExternalRuleStorage externalRuleStorage = null;
|
||||
|
||||
ControlRuleChangeActivator controlRuleChangeActivator = null;
|
||||
|
||||
private RuleStorageProxy() {
|
||||
String externalStorageType = ControlConfigs.getInstance().getRuleExternalStorage();
|
||||
if (StringUtils.isNotEmpty(externalStorageType)) {
|
||||
buildExternalStorage(externalStorageType);
|
||||
}
|
||||
initLocalStorage();
|
||||
controlRuleChangeActivator = new ControlRuleChangeActivator();
|
||||
}
|
||||
|
||||
private void buildExternalStorage(String externalStorageType) {
|
||||
Collection<ExternalRuleStorageBuilder> externalRuleStorageBuilders = NacosServiceLoader
|
||||
.load(ExternalRuleStorageBuilder.class);
|
||||
for (ExternalRuleStorageBuilder each : externalRuleStorageBuilders) {
|
||||
LOGGER.info("Found persist rule storage of name : {}", externalStorageType);
|
||||
if (externalStorageType.equalsIgnoreCase(each.getName())) {
|
||||
try {
|
||||
externalRuleStorage = each.buildExternalRuleStorage();
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Build external rule storage failed, the rules will not be persisted", e);
|
||||
}
|
||||
LOGGER.info("Build external rule storage of name {} finished", externalStorageType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (externalRuleStorage == null && StringUtils.isNotBlank(externalStorageType)) {
|
||||
LOGGER.error("Fail to found persist rule storage of name : {}", externalStorageType);
|
||||
}
|
||||
}
|
||||
|
||||
private void initLocalStorage() {
|
||||
localDiskRuleStorage = new LocalDiskRuleStorage();
|
||||
if (StringUtils.isNotBlank(ControlConfigs.getInstance().getLocalRuleStorageBaseDir())) {
|
||||
localDiskRuleStorage.setLocalRuleBaseDir(ControlConfigs.getInstance().getLocalRuleStorageBaseDir());
|
||||
}
|
||||
}
|
||||
|
||||
public RuleStorage getLocalDiskStorage() {
|
||||
return localDiskRuleStorage;
|
||||
}
|
||||
|
||||
public RuleStorage getExternalStorage() {
|
||||
return externalRuleStorage;
|
||||
}
|
||||
|
||||
public static RuleStorageProxy getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.spi;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.connection.ConnectionControlManager;
|
||||
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
|
||||
|
||||
/**
|
||||
* Nacos control plugin manager builder SPI.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface ControlManagerBuilder {
|
||||
|
||||
/**
|
||||
* Get plugin name.
|
||||
*
|
||||
* @return name of plugin
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Build {@link ConnectionControlManager} implementation for current plugin.
|
||||
*
|
||||
* @return ConnectionControlManager implementation
|
||||
*/
|
||||
ConnectionControlManager buildConnectionControlManager();
|
||||
|
||||
/**
|
||||
* Build {@link TpsControlManager} implementation for current plugin.
|
||||
*
|
||||
* @return TpsControlManager implementation
|
||||
*/
|
||||
TpsControlManager buildTpsControlManager();
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.spi;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.ExternalRuleStorage;
|
||||
|
||||
/**
|
||||
* Nacos control plugin external rule storage builder SPI.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface ExternalRuleStorageBuilder {
|
||||
|
||||
/**
|
||||
* Get plugin name.
|
||||
*
|
||||
* @return name of plugin
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Build {@link ExternalRuleStorage} implementation for current plugin if necessary.
|
||||
*
|
||||
* @return ExternalRuleStorage implementation
|
||||
*/
|
||||
ExternalRuleStorage buildExternalRuleStorage();
|
||||
}
|
||||
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.TpsBarrier;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.TpsCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsResultCode;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* nacos tps control manager.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class DefaultTpsControlManager extends TpsControlManager {
|
||||
|
||||
/**
|
||||
* point name -> tps barrier.
|
||||
*/
|
||||
protected final Map<String, TpsBarrier> points = new ConcurrentHashMap<>(16);
|
||||
|
||||
/**
|
||||
* point name -> tps control rule.
|
||||
*/
|
||||
protected final Map<String, TpsControlRule> rules = new ConcurrentHashMap<>(16);
|
||||
|
||||
public DefaultTpsControlManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* apple tps rule.
|
||||
*
|
||||
* @param pointName pointName.
|
||||
*/
|
||||
public synchronized void registerTpsPoint(String pointName) {
|
||||
if (!points.containsKey(pointName)) {
|
||||
points.put(pointName, tpsBarrierCreator.createTpsBarrier(pointName));
|
||||
if (rules.containsKey(pointName)) {
|
||||
points.get(pointName).applyRule(rules.get(pointName));
|
||||
} else {
|
||||
initTpsRule(pointName);
|
||||
}
|
||||
}
|
||||
Loggers.CONTROL
|
||||
.warn("Tps point for {} registered, But tps control manager is no limit implementation.", pointName);
|
||||
}
|
||||
|
||||
/**
|
||||
* apple tps rule.
|
||||
*
|
||||
* @param pointName pointName.
|
||||
* @param rule rule.
|
||||
*/
|
||||
public synchronized void applyTpsRule(String pointName, TpsControlRule rule) {
|
||||
if (rule == null) {
|
||||
rules.remove(pointName);
|
||||
} else {
|
||||
rules.put(pointName, rule);
|
||||
}
|
||||
if (points.containsKey(pointName)) {
|
||||
points.get(pointName).applyRule(rule);
|
||||
}
|
||||
Loggers.CONTROL.warn("Tps rule for point name {} updated, But tps control manager is no limit implementation.",
|
||||
pointName);
|
||||
}
|
||||
|
||||
public Map<String, TpsBarrier> getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
public Map<String, TpsControlRule> getRules() {
|
||||
return rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* check tps result.
|
||||
*
|
||||
* @param tpsRequest TpsRequest.
|
||||
* @return check current tps is allowed.
|
||||
*/
|
||||
public TpsCheckResponse check(TpsCheckRequest tpsRequest) {
|
||||
return new TpsCheckResponse(true, TpsResultCode.CHECK_SKIP, "skip");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "noLimit";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps;
|
||||
|
||||
/**
|
||||
* MonitorType.
|
||||
*
|
||||
* @author liuzunfei
|
||||
* @version $Id: MonitorType.java, v 0.1 2021年01月12日 20:38 PM liuzunfei Exp $
|
||||
*/
|
||||
public enum MonitorType {
|
||||
// monitor mode.
|
||||
MONITOR("monitor", "only monitor ,not reject request."),
|
||||
//intercept mode.
|
||||
INTERCEPT("intercept", "reject request if tps over limit");
|
||||
|
||||
String type;
|
||||
|
||||
String desc;
|
||||
|
||||
MonitorType(String type, String desc) {
|
||||
this.type = type;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.rule.parser.NacosTpsControlRuleParser;
|
||||
import com.alibaba.nacos.plugin.control.rule.parser.TpsControlRuleParser;
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.RuleStorageProxy;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.TpsBarrier;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.creator.DefaultNacosTpsBarrierCreator;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.creator.TpsBarrierCreator;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.TpsCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* abstract tps control manager.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class TpsControlManager {
|
||||
|
||||
private final TpsControlRuleParser tpsControlRuleParser;
|
||||
|
||||
protected final TpsBarrierCreator tpsBarrierCreator;
|
||||
|
||||
protected TpsControlManager() {
|
||||
this.tpsControlRuleParser = buildTpsControlRuleParser();
|
||||
this.tpsBarrierCreator = buildTpsBarrierCreator();
|
||||
}
|
||||
|
||||
public TpsControlRuleParser getTpsControlRuleParser() {
|
||||
return tpsControlRuleParser;
|
||||
}
|
||||
|
||||
protected TpsControlRuleParser buildTpsControlRuleParser() {
|
||||
return new NacosTpsControlRuleParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build tps barrier creator to creator tps barrier for each point.
|
||||
*
|
||||
* @return TpsBarrierCreator implementation for current plugin
|
||||
*/
|
||||
protected TpsBarrierCreator buildTpsBarrierCreator() {
|
||||
return new DefaultNacosTpsBarrierCreator();
|
||||
}
|
||||
|
||||
protected void initTpsRule(String pointName) {
|
||||
RuleStorageProxy ruleStorageProxy = RuleStorageProxy.getInstance();
|
||||
|
||||
String localRuleContent = ruleStorageProxy.getLocalDiskStorage().getTpsRule(pointName);
|
||||
if (StringUtils.isNotBlank(localRuleContent)) {
|
||||
Loggers.CONTROL.info("Found local disk tps control rule of {},content ={}", pointName, localRuleContent);
|
||||
} else if (ruleStorageProxy.getExternalStorage() != null
|
||||
&& ruleStorageProxy.getExternalStorage().getTpsRule(pointName) != null) {
|
||||
localRuleContent = ruleStorageProxy.getExternalStorage().getTpsRule(pointName);
|
||||
if (StringUtils.isNotBlank(localRuleContent)) {
|
||||
Loggers.CONTROL.info("Found external tps control rule of {},content ={}", pointName, localRuleContent);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(localRuleContent)) {
|
||||
TpsControlRule tpsLimitRule = tpsControlRuleParser.parseRule(localRuleContent);
|
||||
this.applyTpsRule(pointName, tpsLimitRule);
|
||||
} else {
|
||||
Loggers.CONTROL.info("No tps control rule of {} found,content ={} ", pointName, localRuleContent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* apple tps rule.
|
||||
*
|
||||
* @param pointName pointName.
|
||||
*/
|
||||
public abstract void registerTpsPoint(String pointName);
|
||||
|
||||
/**
|
||||
* get points.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract Map<String, TpsBarrier> getPoints();
|
||||
|
||||
/**
|
||||
* get rules.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract Map<String, TpsControlRule> getRules();
|
||||
|
||||
/**
|
||||
* apple tps rule.
|
||||
*
|
||||
* @param pointName pointName.
|
||||
* @param rule rule.
|
||||
*/
|
||||
public abstract void applyTpsRule(String pointName, TpsControlRule rule);
|
||||
|
||||
/**
|
||||
* check tps result.
|
||||
*
|
||||
* @param tpsRequest TpsRequest.
|
||||
* @return check current tps is allowed.
|
||||
*/
|
||||
public abstract TpsCheckResponse check(TpsCheckRequest tpsRequest);
|
||||
|
||||
/**
|
||||
* get control manager name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getName();
|
||||
}
|
||||
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* tps metrics.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class TpsMetrics {
|
||||
|
||||
private String pointName;
|
||||
|
||||
private String type;
|
||||
|
||||
private long timeStamp;
|
||||
|
||||
private TimeUnit period;
|
||||
|
||||
private Counter counter;
|
||||
|
||||
public TpsMetrics(String pointName, String type, long timeStamp, TimeUnit period) {
|
||||
this.pointName = pointName;
|
||||
this.type = type;
|
||||
this.timeStamp = timeStamp;
|
||||
this.period = period;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TpsMetrics{" + "pointName='" + pointName + '\'' + ", type='" + type + '\'' + ", timeStamp=" + timeStamp
|
||||
+ ", period=" + period + ", counter=" + counter + '}';
|
||||
}
|
||||
|
||||
public String getTimeFormatOfSecond(long timeStamp) {
|
||||
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(timeStamp));
|
||||
return format;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
|
||||
return String.join("|", pointName, type, period.name(), getTimeFormatOfSecond(timeStamp),
|
||||
String.valueOf(counter.passCount), String.valueOf(counter.deniedCount));
|
||||
}
|
||||
|
||||
public String getPointName() {
|
||||
return pointName;
|
||||
}
|
||||
|
||||
public void setPointName(String pointName) {
|
||||
this.pointName = pointName;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public long getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
public void setTimeStamp(long timeStamp) {
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
public TimeUnit getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
public void setPeriod(TimeUnit period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
public Counter getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
public void setCounter(Counter counter) {
|
||||
this.counter = counter;
|
||||
}
|
||||
|
||||
public static class Counter {
|
||||
|
||||
private long passCount;
|
||||
|
||||
private long deniedCount;
|
||||
|
||||
public Counter(long passCount, long deniedCount) {
|
||||
this.passCount = passCount;
|
||||
this.deniedCount = deniedCount;
|
||||
}
|
||||
|
||||
public long getPassCount() {
|
||||
return passCount;
|
||||
}
|
||||
|
||||
public void setPassCount(long passCount) {
|
||||
this.passCount = passCount;
|
||||
}
|
||||
|
||||
public long getDeniedCount() {
|
||||
return deniedCount;
|
||||
}
|
||||
|
||||
public void setDeniedCount(long deniedCount) {
|
||||
this.deniedCount = deniedCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + "passCount=" + passCount + ", deniedCount=" + deniedCount + '}';
|
||||
}
|
||||
|
||||
public String getSimpleLog() {
|
||||
return String.join("|", String.valueOf(passCount), String.valueOf(deniedCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.Loggers;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.BarrierCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.TpsCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.RuleDetail;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
|
||||
/**
|
||||
* tps barrier for tps point.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class DefaultNacosTpsBarrier extends TpsBarrier {
|
||||
|
||||
public DefaultNacosTpsBarrier(String pointName) {
|
||||
super(pointName);
|
||||
}
|
||||
|
||||
/**
|
||||
* apply tps.
|
||||
*
|
||||
* @param tpsCheckRequest tpsCheckRequest.
|
||||
* @return check current tps is allowed.
|
||||
*/
|
||||
public TpsCheckResponse applyTps(TpsCheckRequest tpsCheckRequest) {
|
||||
|
||||
BarrierCheckRequest pointCheckRequest = new BarrierCheckRequest();
|
||||
pointCheckRequest.setCount(tpsCheckRequest.getCount());
|
||||
pointCheckRequest.setPointName(super.getPointName());
|
||||
pointCheckRequest.setTimestamp(tpsCheckRequest.getTimestamp());
|
||||
return super.getPointBarrier().applyTps(pointCheckRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* apply rule.
|
||||
*
|
||||
* @param newControlRule newControlRule.
|
||||
*/
|
||||
public synchronized void applyRule(TpsControlRule newControlRule) {
|
||||
Loggers.CONTROL.info("Apply tps control rule start,pointName=[{}] ", this.getPointName());
|
||||
|
||||
//1.reset all monitor point for null.
|
||||
if (newControlRule == null || newControlRule.getPointRule() == null) {
|
||||
Loggers.CONTROL.info("Clear all tps control rule ,pointName=[{}] ", this.getPointName());
|
||||
super.getPointBarrier().clearLimitRule();
|
||||
return;
|
||||
}
|
||||
|
||||
//2.check point rule.
|
||||
RuleDetail newPointRule = newControlRule.getPointRule();
|
||||
|
||||
Loggers.CONTROL.info("Update point control rule ,pointName=[{}],original maxTps={}, new maxTps={}"
|
||||
+ ",original monitorType={}, original monitorType={}, ", this.getPointName(),
|
||||
this.pointBarrier.getMaxCount(), newPointRule.getMaxCount(), this.pointBarrier.getMonitorType(),
|
||||
newPointRule.getMonitorType());
|
||||
this.pointBarrier.applyRuleDetail(newPointRule);
|
||||
|
||||
Loggers.CONTROL.info("Apply tps control rule end,pointName=[{}] ", this.getPointName());
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* local simple count rate counter.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class LocalSimpleCountRateCounter extends RateCounter {
|
||||
|
||||
private static final int DEFAULT_RECORD_SIZE = 10;
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
private List<TpsSlot> slotList;
|
||||
|
||||
public LocalSimpleCountRateCounter(String name, TimeUnit period) {
|
||||
super(name, period);
|
||||
slotList = new ArrayList<>(DEFAULT_RECORD_SIZE);
|
||||
for (int i = 0; i < DEFAULT_RECORD_SIZE; i++) {
|
||||
slotList.add(new TpsSlot());
|
||||
}
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
if (period == TimeUnit.SECONDS) {
|
||||
startTime = RateCounter.getTrimMillsOfSecond(now);
|
||||
} else if (period == TimeUnit.MINUTES) {
|
||||
startTime = RateCounter.getTrimMillsOfMinute(now);
|
||||
} else if (period == TimeUnit.HOURS) {
|
||||
startTime = RateCounter.getTrimMillsOfHour(now);
|
||||
} else {
|
||||
//second default
|
||||
startTime = RateCounter.getTrimMillsOfSecond(now);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long add(long timestamp, long count) {
|
||||
return createSlotIfAbsent(timestamp).countHolder.count.addAndGet(count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdd(long timestamp, long countDelta, long upperLimit) {
|
||||
if (createSlotIfAbsent(timestamp).countHolder.count.addAndGet(countDelta) <= upperLimit) {
|
||||
return true;
|
||||
} else {
|
||||
createSlotIfAbsent(timestamp).countHolder.interceptedCount.addAndGet(countDelta);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void minus(long timestamp, long count) {
|
||||
AtomicLong currentCount = createSlotIfAbsent(timestamp).countHolder.count;
|
||||
currentCount.addAndGet(count * -1);
|
||||
}
|
||||
|
||||
public long getCount(long timestamp) {
|
||||
TpsSlot point = getPoint(timestamp);
|
||||
return point == null ? 0L : point.countHolder.count.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* get slot of the timestamp second,read only ,return nul if not exist.
|
||||
*
|
||||
* @param timeStamp the timestamp second.
|
||||
* @return tps slot.
|
||||
*/
|
||||
private TpsSlot getPoint(long timeStamp) {
|
||||
long distance = timeStamp - startTime;
|
||||
long diff = (distance < 0 ? distance + getPeriod().toMillis(1) * DEFAULT_RECORD_SIZE : distance) / getPeriod()
|
||||
.toMillis(1);
|
||||
long currentWindowTime = startTime + diff * getPeriod().toMillis(1);
|
||||
int index = (int) diff % DEFAULT_RECORD_SIZE;
|
||||
TpsSlot tpsSlot = slotList.get(index);
|
||||
if (tpsSlot.time != currentWindowTime) {
|
||||
return null;
|
||||
}
|
||||
return tpsSlot;
|
||||
}
|
||||
|
||||
/**
|
||||
* get slot of the timestamp second,create if not exist.
|
||||
*
|
||||
* @param timeStamp the timestamp second.
|
||||
* @return tps slot.
|
||||
*/
|
||||
public TpsSlot createSlotIfAbsent(long timeStamp) {
|
||||
long distance = timeStamp - startTime;
|
||||
|
||||
long diff = (distance < 0 ? distance + getPeriod().toMillis(1) * DEFAULT_RECORD_SIZE : distance) / getPeriod()
|
||||
.toMillis(1);
|
||||
long currentWindowTime = startTime + diff * getPeriod().toMillis(1);
|
||||
int index = (int) diff % DEFAULT_RECORD_SIZE;
|
||||
TpsSlot tpsSlot = slotList.get(index);
|
||||
if (tpsSlot.time != currentWindowTime) {
|
||||
tpsSlot.reset(currentWindowTime);
|
||||
}
|
||||
return slotList.get(index);
|
||||
}
|
||||
|
||||
static class TpsSlot {
|
||||
|
||||
long time = 0L;
|
||||
|
||||
private SlotCountHolder countHolder = new SlotCountHolder();
|
||||
|
||||
public void reset(long second) {
|
||||
synchronized (this) {
|
||||
if (this.time != second) {
|
||||
this.time = second;
|
||||
countHolder.count.set(0L);
|
||||
countHolder.interceptedCount.set(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TpsSlot{" + "time=" + time + ", countHolder=" + countHolder + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class SlotCountHolder {
|
||||
|
||||
AtomicLong count = new AtomicLong();
|
||||
|
||||
AtomicLong interceptedCount = new AtomicLong();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + count + "|" + interceptedCount + '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* local simple count rule barrier.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class LocalSimpleCountRuleBarrier extends SimpleCountRuleBarrier {
|
||||
|
||||
public LocalSimpleCountRuleBarrier(String pointName, String ruleName, TimeUnit period) {
|
||||
super(pointName, ruleName, period);
|
||||
}
|
||||
|
||||
public RateCounter createSimpleCounter(String name, TimeUnit period) {
|
||||
return new LocalSimpleCountRateCounter(name, period);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBarrierName() {
|
||||
return "localsimplecount";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* abstract rate counter.
|
||||
*
|
||||
* @author zunfei.lzf
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class RateCounter {
|
||||
|
||||
/**
|
||||
* rate count name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* rate period.
|
||||
*/
|
||||
private TimeUnit period;
|
||||
|
||||
public RateCounter(String name, TimeUnit period) {
|
||||
this.name = name;
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
public TimeUnit getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
/**
|
||||
* add count for the second of timestamp.
|
||||
*
|
||||
* @param timestamp timestamp.
|
||||
* @param count count.
|
||||
* @return
|
||||
*/
|
||||
public abstract long add(long timestamp, long count);
|
||||
|
||||
/**
|
||||
* add intercepted count for the second of timestamp.
|
||||
*
|
||||
* @param timestamp timestamp
|
||||
* @param countDelta count
|
||||
* @param upperLimit upperLimit
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean tryAdd(long timestamp, long countDelta, long upperLimit);
|
||||
|
||||
/**
|
||||
* get count of the second of timestamp.
|
||||
*
|
||||
* @param timestamp timestamp.
|
||||
* @return
|
||||
*/
|
||||
public abstract long getCount(long timestamp);
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* get trim mills of second.
|
||||
*
|
||||
* @param timeStamp timestamp milliseconds.
|
||||
* @return
|
||||
*/
|
||||
public static long getTrimMillsOfMinute(long timeStamp) {
|
||||
String millString = String.valueOf(timeStamp);
|
||||
String substring = millString.substring(0, millString.length() - 3);
|
||||
return Long.valueOf(Long.valueOf(substring) / 60 * 60 + "000");
|
||||
}
|
||||
|
||||
/**
|
||||
* get trim mills of second.
|
||||
*
|
||||
* @param timeStamp timestamp milliseconds.
|
||||
* @return
|
||||
*/
|
||||
public static long getTrimMillsOfSecond(long timeStamp) {
|
||||
String millString = String.valueOf(timeStamp);
|
||||
String substring = millString.substring(0, millString.length() - 3);
|
||||
return Long.valueOf(substring + "000");
|
||||
}
|
||||
|
||||
/**
|
||||
* get trim mills of second.
|
||||
*
|
||||
* @param timeStamp timestamp milliseconds.
|
||||
* @return
|
||||
*/
|
||||
public static long getTrimMillsOfHour(long timeStamp) {
|
||||
String millString = String.valueOf(timeStamp);
|
||||
String substring = millString.substring(0, millString.length() - 3);
|
||||
return Long.valueOf(Long.valueOf(substring) / (60 * 60) * (60 * 60) + "000");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier;
|
||||
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.plugin.control.tps.MonitorType;
|
||||
import com.alibaba.nacos.plugin.control.tps.TpsMetrics;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.BarrierCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.RuleDetail;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* rule barrier.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class RuleBarrier {
|
||||
|
||||
private TimeUnit period;
|
||||
|
||||
private String pointName;
|
||||
|
||||
private long maxCount;
|
||||
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* monitor/intercept.
|
||||
*/
|
||||
private String monitorType = MonitorType.MONITOR.getType();
|
||||
|
||||
public String getRuleName() {
|
||||
return ruleName;
|
||||
}
|
||||
|
||||
public void setRuleName(String ruleName) {
|
||||
this.ruleName = ruleName;
|
||||
}
|
||||
|
||||
public String getPointName() {
|
||||
return pointName;
|
||||
}
|
||||
|
||||
public void setPointName(String pointName) {
|
||||
this.pointName = pointName;
|
||||
}
|
||||
|
||||
public TimeUnit getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
public void setPeriod(TimeUnit period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
/**
|
||||
* get barrier name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getBarrierName();
|
||||
|
||||
public long getMaxCount() {
|
||||
return maxCount;
|
||||
}
|
||||
|
||||
public void setMaxCount(long maxCount) {
|
||||
this.maxCount = maxCount;
|
||||
}
|
||||
|
||||
public String getMonitorType() {
|
||||
return monitorType;
|
||||
}
|
||||
|
||||
public void setMonitorType(String monitorType) {
|
||||
this.monitorType = monitorType;
|
||||
}
|
||||
|
||||
public boolean isMonitorType() {
|
||||
return MonitorType.MONITOR.getType().equalsIgnoreCase(this.monitorType);
|
||||
}
|
||||
|
||||
public String getLimitMsg() {
|
||||
Map<String, String> limitMsg = new HashMap<>(3);
|
||||
limitMsg.put("deniedType", "point");
|
||||
limitMsg.put("period", period.toString());
|
||||
limitMsg.put("limitCount", String.valueOf(maxCount));
|
||||
return JacksonUtils.toJson(limitMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* apply tps.
|
||||
*
|
||||
* @param barrierCheckRequest barrierCheckRequest.
|
||||
* @return
|
||||
*/
|
||||
public abstract TpsCheckResponse applyTps(BarrierCheckRequest barrierCheckRequest);
|
||||
|
||||
/**
|
||||
* apply rule detail.
|
||||
*
|
||||
* @param ruleDetail ruleDetail.
|
||||
*/
|
||||
public abstract void applyRuleDetail(RuleDetail ruleDetail);
|
||||
|
||||
/**
|
||||
* get metrics.
|
||||
*
|
||||
* @param timeStamp timeStamp.
|
||||
* @return
|
||||
*/
|
||||
public abstract TpsMetrics getMetrics(long timeStamp);
|
||||
|
||||
/**
|
||||
* clear limit rule.
|
||||
*/
|
||||
public void clearLimitRule() {
|
||||
this.maxCount = -1;
|
||||
this.monitorType = MonitorType.MONITOR.getType();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.MonitorType;
|
||||
import com.alibaba.nacos.plugin.control.tps.TpsMetrics;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.BarrierCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsResultCode;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.RuleDetail;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* simple count rule barrier.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class SimpleCountRuleBarrier extends RuleBarrier {
|
||||
|
||||
RateCounter rateCounter;
|
||||
|
||||
public SimpleCountRuleBarrier(String pointName, String ruleName, TimeUnit period) {
|
||||
super.setPointName(pointName);
|
||||
super.setPeriod(period);
|
||||
super.setRuleName(ruleName);
|
||||
this.rateCounter = createSimpleCounter(ruleName, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* create rate count.
|
||||
*
|
||||
* @param name name.
|
||||
* @param period period.
|
||||
* @return
|
||||
*/
|
||||
public abstract RateCounter createSimpleCounter(String name, TimeUnit period);
|
||||
|
||||
public void reCreateRaterCounter(String name, TimeUnit period) {
|
||||
this.rateCounter = createSimpleCounter(name, period);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TpsCheckResponse applyTps(BarrierCheckRequest barrierCheckRequest) {
|
||||
if (MonitorType.INTERCEPT.getType().equals(getMonitorType())) {
|
||||
long maxCount = getMaxCount();
|
||||
boolean accepted = rateCounter.tryAdd(barrierCheckRequest.getTimestamp(), barrierCheckRequest.getCount(), maxCount);
|
||||
return accepted ? new TpsCheckResponse(true, TpsResultCode.PASS_BY_POINT, "success") :
|
||||
new TpsCheckResponse(false, TpsResultCode.DENY_BY_POINT, "tps over limit :" + maxCount);
|
||||
} else {
|
||||
rateCounter.add(barrierCheckRequest.getTimestamp(), barrierCheckRequest.getCount());
|
||||
return new TpsCheckResponse(true, TpsResultCode.PASS_BY_POINT, "success");
|
||||
}
|
||||
}
|
||||
|
||||
long trimTimeStamp(long timeStamp) {
|
||||
if (this.getPeriod() == TimeUnit.SECONDS) {
|
||||
timeStamp = RateCounter.getTrimMillsOfSecond(timeStamp);
|
||||
} else if (this.getPeriod() == TimeUnit.MINUTES) {
|
||||
timeStamp = RateCounter.getTrimMillsOfMinute(timeStamp);
|
||||
} else if (this.getPeriod() == TimeUnit.HOURS) {
|
||||
timeStamp = RateCounter.getTrimMillsOfHour(timeStamp);
|
||||
} else {
|
||||
//second default
|
||||
timeStamp = RateCounter.getTrimMillsOfSecond(timeStamp);
|
||||
}
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TpsMetrics getMetrics(long timeStamp) {
|
||||
timeStamp = trimTimeStamp(timeStamp);
|
||||
|
||||
TpsMetrics tpsMetrics = new TpsMetrics("", "", timeStamp, super.getPeriod());
|
||||
long totalPass = rateCounter.getCount(timeStamp);
|
||||
if (totalPass <= 0) {
|
||||
return null;
|
||||
}
|
||||
tpsMetrics.setCounter(new TpsMetrics.Counter(totalPass, 0));
|
||||
return tpsMetrics;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* apply rule detail.
|
||||
*
|
||||
* @param ruleDetail ruleDetail.
|
||||
*/
|
||||
public void applyRuleDetail(RuleDetail ruleDetail) {
|
||||
|
||||
if (!Objects.equals(this.getPeriod(), ruleDetail.getPeriod())) {
|
||||
this.setMaxCount(ruleDetail.getMaxCount());
|
||||
this.setMonitorType(ruleDetail.getMonitorType());
|
||||
this.setPeriod(ruleDetail.getPeriod());
|
||||
reCreateRaterCounter(ruleDetail.getRuleName(), this.getPeriod());
|
||||
} else {
|
||||
this.setMaxCount(ruleDetail.getMaxCount());
|
||||
this.setMonitorType(ruleDetail.getMonitorType());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.creator.RuleBarrierCreator;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.creator.LocalSimpleCountBarrierCreator;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.TpsCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* tps barrier for tps point.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class TpsBarrier {
|
||||
|
||||
protected RuleBarrierCreator ruleBarrierCreator;
|
||||
|
||||
protected String pointName;
|
||||
|
||||
protected RuleBarrier pointBarrier;
|
||||
|
||||
public TpsBarrier(String pointName) {
|
||||
this.pointName = pointName;
|
||||
this.ruleBarrierCreator = new LocalSimpleCountBarrierCreator();
|
||||
this.pointBarrier = ruleBarrierCreator.createRuleBarrier(pointName, pointName, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* apply tps.
|
||||
*
|
||||
* @param tpsCheckRequest tpsCheckRequest.
|
||||
* @return check current tps is allowed.
|
||||
*/
|
||||
public abstract TpsCheckResponse applyTps(TpsCheckRequest tpsCheckRequest);
|
||||
|
||||
public RuleBarrier getPointBarrier() {
|
||||
return pointBarrier;
|
||||
}
|
||||
|
||||
public String getPointName() {
|
||||
return pointName;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply rule.
|
||||
*
|
||||
* @param newControlRule newControlRule.
|
||||
*/
|
||||
public abstract void applyRule(TpsControlRule newControlRule);
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier.creator;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.TpsBarrier;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.DefaultNacosTpsBarrier;
|
||||
|
||||
/**
|
||||
* default nacos tps barrier creator.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class DefaultNacosTpsBarrierCreator implements TpsBarrierCreator {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "nacos";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TpsBarrier createTpsBarrier(String pointName) {
|
||||
return new DefaultNacosTpsBarrier(pointName);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier.creator;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.RuleBarrier;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.LocalSimpleCountRuleBarrier;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* local simple count barrier creator.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class LocalSimpleCountBarrierCreator implements RuleBarrierCreator {
|
||||
|
||||
private static final LocalSimpleCountBarrierCreator INSTANCE = new LocalSimpleCountBarrierCreator();
|
||||
|
||||
public LocalSimpleCountBarrierCreator() {
|
||||
}
|
||||
|
||||
public static final LocalSimpleCountBarrierCreator getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleBarrier createRuleBarrier(String pointName, String ruleName, TimeUnit period) {
|
||||
return new LocalSimpleCountRuleBarrier(pointName, ruleName, period);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "localsimplecountor";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier.creator;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.RuleBarrier;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* rule barrier creator.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public interface RuleBarrierCreator {
|
||||
|
||||
/**
|
||||
* create a count for time unit period.
|
||||
*
|
||||
* @param pointName pointName.
|
||||
* @param ruleName ruleName.
|
||||
* @param period period.
|
||||
* @return
|
||||
*/
|
||||
RuleBarrier createRuleBarrier(String pointName, String ruleName, TimeUnit period);
|
||||
|
||||
/**
|
||||
* rate count creator name.
|
||||
*
|
||||
* @return name.
|
||||
*/
|
||||
String name();
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.tps.barrier.creator;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.TpsBarrier;
|
||||
|
||||
/**
|
||||
* tps barrier creator.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public interface TpsBarrierCreator {
|
||||
|
||||
/**
|
||||
* get name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* create tps barrier.
|
||||
*
|
||||
* @param pointName pointName.
|
||||
* @return
|
||||
*/
|
||||
TpsBarrier createTpsBarrier(String pointName);
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps.request;
|
||||
|
||||
/**
|
||||
* barrier check request.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class BarrierCheckRequest {
|
||||
|
||||
private String pointName;
|
||||
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
|
||||
private long count = 1;
|
||||
|
||||
public String getPointName() {
|
||||
return pointName;
|
||||
}
|
||||
|
||||
public void setPointName(String pointName) {
|
||||
this.pointName = pointName;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(long count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps.request;
|
||||
|
||||
/**
|
||||
* tps request.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class TpsCheckRequest {
|
||||
|
||||
private String pointName;
|
||||
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
|
||||
private String connectionId;
|
||||
|
||||
private String clientIp;
|
||||
|
||||
private long count = 1;
|
||||
|
||||
public TpsCheckRequest() {
|
||||
|
||||
}
|
||||
|
||||
public TpsCheckRequest(String pointName, String connectionId, String clientIp) {
|
||||
this.connectionId = connectionId;
|
||||
this.clientIp = clientIp;
|
||||
this.pointName = pointName;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getConnectionId() {
|
||||
return connectionId;
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(long count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public void setConnectionId(String connectionId) {
|
||||
this.connectionId = connectionId;
|
||||
}
|
||||
|
||||
public String getClientIp() {
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
public void setClientIp(String clientIp) {
|
||||
this.clientIp = clientIp;
|
||||
}
|
||||
|
||||
public String getPointName() {
|
||||
return pointName;
|
||||
}
|
||||
|
||||
public void setPointName(String pointName) {
|
||||
this.pointName = pointName;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps.response;
|
||||
|
||||
/**
|
||||
* tps response.
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class TpsCheckResponse {
|
||||
|
||||
private boolean success;
|
||||
|
||||
private int code;
|
||||
|
||||
private String message;
|
||||
|
||||
public TpsCheckResponse(boolean success, int code, String message) {
|
||||
this.success = success;
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps.response;
|
||||
|
||||
/**
|
||||
* tps result code.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class TpsResultCode {
|
||||
|
||||
public static final int PASS_BY_POINT = 200;
|
||||
|
||||
/**
|
||||
* rule denied,but pass by monitor.
|
||||
*/
|
||||
public static final int PASS_BY_MONITOR = 201;
|
||||
|
||||
/**
|
||||
* deny by point rule.
|
||||
*/
|
||||
public static final int DENY_BY_POINT = 300;
|
||||
|
||||
/**
|
||||
* skip.
|
||||
*/
|
||||
public static final int CHECK_SKIP = 100;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps.rule;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* rule detail.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public class RuleDetail {
|
||||
|
||||
String ruleName;
|
||||
|
||||
long maxCount = -1;
|
||||
|
||||
TimeUnit period = TimeUnit.SECONDS;
|
||||
|
||||
/**
|
||||
* monitor/intercept.
|
||||
*/
|
||||
String monitorType = "";
|
||||
|
||||
public RuleDetail() {
|
||||
|
||||
}
|
||||
|
||||
public String getRuleName() {
|
||||
return ruleName;
|
||||
}
|
||||
|
||||
public void setRuleName(String ruleName) {
|
||||
this.ruleName = ruleName;
|
||||
}
|
||||
|
||||
public TimeUnit getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
public void setPeriod(TimeUnit period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
public long getMaxCount() {
|
||||
return maxCount;
|
||||
}
|
||||
|
||||
public void setMaxCount(long maxCount) {
|
||||
this.maxCount = maxCount;
|
||||
}
|
||||
|
||||
public String getMonitorType() {
|
||||
return monitorType;
|
||||
}
|
||||
|
||||
public void setMonitorType(String monitorType) {
|
||||
this.monitorType = monitorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Rule{" + "maxTps=" + maxCount + ", monitorType='" + monitorType + '\'' + '}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps.rule;
|
||||
|
||||
/**
|
||||
* rule model.
|
||||
*
|
||||
* @author shiyiyue
|
||||
*/
|
||||
public enum RuleModel {
|
||||
|
||||
/**
|
||||
* every single monitor key will be counted as one counter.
|
||||
*/
|
||||
FUZZY("FUZZY", "every single monitor key will be counted as one counter"),
|
||||
|
||||
/**
|
||||
* every single monitor key will be counted as different counter.
|
||||
*/
|
||||
PROTO("PROTO", "every single monitor key will be counted as different counter");
|
||||
|
||||
private String model;
|
||||
|
||||
private String desc;
|
||||
|
||||
RuleModel(String model, String desc) {
|
||||
this.model = model;
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps.rule;
|
||||
|
||||
/**
|
||||
* tps control point.
|
||||
*
|
||||
* @author liuzunfei
|
||||
* @version $Id: TpsControlPoint.java, v 0.1 2021年01月09日 12:38 PM liuzunfei Exp $
|
||||
*/
|
||||
public class TpsControlRule {
|
||||
|
||||
private String pointName;
|
||||
|
||||
private RuleDetail pointRule;
|
||||
|
||||
public String getPointName() {
|
||||
return pointName;
|
||||
}
|
||||
|
||||
public void setPointName(String pointName) {
|
||||
this.pointName = pointName;
|
||||
}
|
||||
|
||||
public RuleDetail getPointRule() {
|
||||
return pointRule;
|
||||
}
|
||||
|
||||
public void setPointRule(RuleDetail pointRule) {
|
||||
this.pointRule = pointRule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TpsControlRule{" + "pointName='" + pointName + '\'' + ", pointRule=" + pointRule + "}'";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,556 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.ByteUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.CheckedInputStream;
|
||||
import java.util.zip.CheckedOutputStream;
|
||||
import java.util.zip.Checksum;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* IO operates on the utility class.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public final class DiskUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DiskUtils.class);
|
||||
|
||||
private static final String NO_SPACE_CN = "设备上没有空间";
|
||||
|
||||
private static final String NO_SPACE_EN = "No space left on device";
|
||||
|
||||
private static final String DISK_QUOTA_CN = "超出磁盘限额";
|
||||
|
||||
private static final String DISK_QUOTA_EN = "Disk quota exceeded";
|
||||
|
||||
private static final Charset CHARSET = StandardCharsets.UTF_8;
|
||||
|
||||
private static final CharsetDecoder DECODER = CHARSET.newDecoder();
|
||||
|
||||
public static void touch(String path, String fileName) throws IOException {
|
||||
FileUtils.touch(Paths.get(path, fileName).toFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the same behaviour as the "touch" utility on Unix. It creates a new file with size 0 or, if the file
|
||||
* exists already, it is opened and closed without modifying it, but updating the file date and time.
|
||||
*
|
||||
* <p>NOTE: As from v1.3, this method throws an IOException if the last
|
||||
* modified date of the file cannot be set. Also, as from v1.3 this method creates parent directories if they do not
|
||||
* exist.
|
||||
*
|
||||
* @param file the File to touch
|
||||
* @throws IOException If an I/O problem occurs
|
||||
*/
|
||||
public static void touch(File file) throws IOException {
|
||||
FileUtils.touch(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its
|
||||
* name. The resulting {@code Path} is associated with the same {@code FileSystem} as the given directory.
|
||||
*
|
||||
* <p>The details as to how the name of the file is constructed is
|
||||
* implementation dependent and therefore not specified. Where possible the {@code prefix} and {@code suffix} are
|
||||
* used to construct candidate names in the same manner as the {@link File#createTempFile(String, String,
|
||||
* File)} method.
|
||||
*
|
||||
* @param dir the path to directory in which to create the file
|
||||
* @param prefix the prefix string to be used in generating the file's name; may be {@code null}
|
||||
* @param suffix the suffix string to be used in generating the file's name; may be {@code null}, in which case
|
||||
* "{@code .tmp}" is used
|
||||
* @return the path to the newly created file that did not exist before this method was invoked
|
||||
* @throws IllegalArgumentException if the prefix or suffix parameters cannot be used to generate a candidate
|
||||
* file name
|
||||
* @throws UnsupportedOperationException if the array contains an attribute that cannot be set atomically when
|
||||
* creating the directory
|
||||
* @throws IOException if an I/O error occurs or {@code dir} does not exist
|
||||
* @throws SecurityException In the case of the default provider, and a security manager is installed,
|
||||
* the {@link SecurityManager#checkWrite(String) checkWrite} method is invoked
|
||||
* to check write access to the file.
|
||||
*/
|
||||
public static File createTmpFile(String dir, String prefix, String suffix) throws IOException {
|
||||
return Files.createTempFile(Paths.get(dir), prefix, suffix).toFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its
|
||||
* name. The resulting {@code Path} is associated with the default {@code FileSystem}.
|
||||
*
|
||||
* @param prefix the prefix string to be used in generating the file's name; may be {@code null}
|
||||
* @param suffix the suffix string to be used in generating the file's name; may be {@code null}, in which case
|
||||
* "{@code .tmp}" is used
|
||||
* @return the path to the newly created file that did not exist before this method was invoked
|
||||
* @throws IllegalArgumentException if the prefix or suffix parameters cannot be used to generate a candidate
|
||||
* file name
|
||||
* @throws UnsupportedOperationException if the array contains an attribute that cannot be set atomically when
|
||||
* creating the directory
|
||||
* @throws IOException if an I/O error occurs or the temporary-file directory does not exist
|
||||
* @throws SecurityException In the case of the default provider, and a security manager is installed,
|
||||
* the {@link SecurityManager#checkWrite(String) checkWrite} method is invoked
|
||||
* to check write access to the file.
|
||||
*/
|
||||
public static File createTmpFile(String prefix, String suffix) throws IOException {
|
||||
return Files.createTempFile(prefix, suffix).toFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* read file which under the path.
|
||||
*
|
||||
* @param path directory
|
||||
* @param fileName filename
|
||||
* @return content
|
||||
*/
|
||||
public static String readFile(String path, String fileName) {
|
||||
File file = openFile(path, fileName);
|
||||
if (file.exists()) {
|
||||
return readFile(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* read file content by {@link InputStream}.
|
||||
*
|
||||
* @param is {@link InputStream}
|
||||
* @return content
|
||||
*/
|
||||
public static String readFile(InputStream is) {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
|
||||
StringBuilder textBuilder = new StringBuilder();
|
||||
String lineTxt = null;
|
||||
while ((lineTxt = reader.readLine()) != null) {
|
||||
textBuilder.append(lineTxt);
|
||||
}
|
||||
return textBuilder.toString();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read this file content.
|
||||
*
|
||||
* @param file {@link File}
|
||||
* @return content
|
||||
*/
|
||||
public static String readFile(File file) {
|
||||
try (FileChannel fileChannel = new FileInputStream(file).getChannel()) {
|
||||
StringBuilder text = new StringBuilder();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4096);
|
||||
CharBuffer charBuffer = CharBuffer.allocate(4096);
|
||||
while (fileChannel.read(buffer) != -1) {
|
||||
buffer.flip();
|
||||
DECODER.decode(buffer, charBuffer, false);
|
||||
charBuffer.flip();
|
||||
while (charBuffer.hasRemaining()) {
|
||||
text.append(charBuffer.get());
|
||||
}
|
||||
buffer.clear();
|
||||
charBuffer.clear();
|
||||
}
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read this file content then return bytes.
|
||||
*
|
||||
* @param file {@link File}
|
||||
* @return content bytes
|
||||
*/
|
||||
public static byte[] readFileBytes(File file) {
|
||||
if (file.exists()) {
|
||||
String result = readFile(file);
|
||||
if (result != null) {
|
||||
return ByteUtils.toBytes(result);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] readFileBytes(String path, String fileName) {
|
||||
File file = openFile(path, fileName);
|
||||
return readFileBytes(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents to the target file.
|
||||
*
|
||||
* @param file target file
|
||||
* @param content content
|
||||
* @param append write append mode
|
||||
* @return write success
|
||||
*/
|
||||
public static boolean writeFile(File file, byte[] content, boolean append) {
|
||||
try (FileChannel fileChannel = new FileOutputStream(file, append).getChannel()) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(content);
|
||||
fileChannel.write(buffer);
|
||||
return true;
|
||||
} catch (IOException ioe) {
|
||||
if (ioe.getMessage() != null) {
|
||||
String errMsg = ioe.getMessage();
|
||||
if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg) || errMsg.contains(DISK_QUOTA_CN) || errMsg
|
||||
.contains(DISK_QUOTA_EN)) {
|
||||
LOGGER.warn("磁盘满,自杀退出");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void deleteQuietly(File file) {
|
||||
Objects.requireNonNull(file, "file");
|
||||
FileUtils.deleteQuietly(file);
|
||||
}
|
||||
|
||||
public static void deleteQuietly(Path path) {
|
||||
Objects.requireNonNull(path, "path");
|
||||
FileUtils.deleteQuietly(path.toFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* delete target file.
|
||||
*
|
||||
* @param path directory
|
||||
* @param fileName filename
|
||||
* @return delete success
|
||||
*/
|
||||
public static boolean deleteFile(String path, String fileName) {
|
||||
File file = Paths.get(path, fileName).toFile();
|
||||
if (file.exists()) {
|
||||
return file.delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void deleteDirectory(String path) throws IOException {
|
||||
FileUtils.deleteDirectory(new File(path));
|
||||
}
|
||||
|
||||
public static void forceMkdir(String path) throws IOException {
|
||||
FileUtils.forceMkdir(new File(path));
|
||||
}
|
||||
|
||||
public static void forceMkdir(File file) throws IOException {
|
||||
FileUtils.forceMkdir(file);
|
||||
}
|
||||
|
||||
public static void deleteDirThenMkdir(String path) throws IOException {
|
||||
deleteDirectory(path);
|
||||
forceMkdir(path);
|
||||
}
|
||||
|
||||
public static void copyDirectory(File srcDir, File destDir) throws IOException {
|
||||
FileUtils.copyDirectory(srcDir, destDir);
|
||||
}
|
||||
|
||||
public static void copyFile(File src, File target) throws IOException {
|
||||
FileUtils.copyFile(src, target);
|
||||
}
|
||||
|
||||
public static File openFile(String path, String fileName) {
|
||||
return openFile(path, fileName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* open file.
|
||||
*
|
||||
* @param path directory
|
||||
* @param fileName filename
|
||||
* @param rewrite if rewrite is true, will delete old file and create new one
|
||||
* @return {@link File}
|
||||
*/
|
||||
public static File openFile(String path, String fileName, boolean rewrite) {
|
||||
File directory = new File(path);
|
||||
boolean mkdirs = true;
|
||||
if (!directory.exists()) {
|
||||
mkdirs = directory.mkdirs();
|
||||
}
|
||||
if (!mkdirs) {
|
||||
LOGGER.error("[DiskUtils] can't create directory");
|
||||
return null;
|
||||
}
|
||||
File file = new File(path, fileName);
|
||||
try {
|
||||
boolean create = true;
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
if (file.exists()) {
|
||||
if (rewrite) {
|
||||
file.delete();
|
||||
} else {
|
||||
create = false;
|
||||
}
|
||||
}
|
||||
if (create) {
|
||||
file.createNewFile();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
// copy from sofa-jraft
|
||||
|
||||
/**
|
||||
* Compress a folder in a directory.
|
||||
*
|
||||
* @param rootDir directory
|
||||
* @param sourceDir folder
|
||||
* @param outputFile output file
|
||||
* @param checksum checksum
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static void compress(final String rootDir, final String sourceDir, final String outputFile,
|
||||
final Checksum checksum) throws IOException {
|
||||
try (final FileOutputStream fos = new FileOutputStream(outputFile);
|
||||
final CheckedOutputStream cos = new CheckedOutputStream(fos, checksum);
|
||||
final ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(cos))) {
|
||||
compressDirectoryToZipFile(rootDir, sourceDir, zos);
|
||||
zos.flush();
|
||||
fos.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
// copy from sofa-jraft
|
||||
|
||||
private static void compressDirectoryToZipFile(final String rootDir, final String sourceDir,
|
||||
final ZipOutputStream zos) throws IOException {
|
||||
final String dir = Paths.get(rootDir, sourceDir).toString();
|
||||
final File[] files = Objects.requireNonNull(new File(dir).listFiles(), "files");
|
||||
for (final File file : files) {
|
||||
final String child = Paths.get(sourceDir, file.getName()).toString();
|
||||
if (file.isDirectory()) {
|
||||
compressDirectoryToZipFile(rootDir, child, zos);
|
||||
} else {
|
||||
try (final FileInputStream fis = new FileInputStream(file);
|
||||
final BufferedInputStream bis = new BufferedInputStream(fis)) {
|
||||
compressIntoZipFile(child, bis, zos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress an input stream to zip file.
|
||||
*
|
||||
* @param childName child name in zip file
|
||||
* @param inputStream input stream needed compress
|
||||
* @param outputFile output file
|
||||
* @param checksum check sum
|
||||
* @throws IOException IOException during compress
|
||||
*/
|
||||
public static void compressIntoZipFile(final String childName, final InputStream inputStream,
|
||||
final String outputFile, final Checksum checksum) throws IOException {
|
||||
try (final FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
|
||||
final CheckedOutputStream checkedOutputStream = new CheckedOutputStream(fileOutputStream, checksum);
|
||||
final ZipOutputStream zipStream = new ZipOutputStream(new BufferedOutputStream(checkedOutputStream))) {
|
||||
compressIntoZipFile(childName, inputStream, zipStream);
|
||||
zipStream.flush();
|
||||
fileOutputStream.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
private static void compressIntoZipFile(final String childName, final InputStream inputStream,
|
||||
final ZipOutputStream zipOutputStream) throws IOException {
|
||||
zipOutputStream.putNextEntry(new ZipEntry(childName));
|
||||
IOUtils.copy(inputStream, zipOutputStream);
|
||||
}
|
||||
|
||||
// copy from sofa-jraft
|
||||
|
||||
/**
|
||||
* Unzip the target file to the specified folder.
|
||||
*
|
||||
* @param sourceFile target file
|
||||
* @param outputDir specified folder
|
||||
* @param checksum checksum
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static void decompress(final String sourceFile, final String outputDir, final Checksum checksum)
|
||||
throws IOException {
|
||||
try (final FileInputStream fis = new FileInputStream(sourceFile);
|
||||
final CheckedInputStream cis = new CheckedInputStream(fis, checksum);
|
||||
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(cis))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
final String fileName = entry.getName();
|
||||
final File entryFile = new File(Paths.get(outputDir, fileName).toString());
|
||||
FileUtils.forceMkdir(entryFile.getParentFile());
|
||||
try (final FileOutputStream fos = new FileOutputStream(entryFile);
|
||||
final BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
IOUtils.copy(zis, bos);
|
||||
bos.flush();
|
||||
fos.getFD().sync();
|
||||
}
|
||||
}
|
||||
// Continue to read all remaining bytes(extra metadata of ZipEntry) directly from the checked stream,
|
||||
// Otherwise, the checksum value maybe unexpected.
|
||||
//
|
||||
// See https://coderanch.com/t/279175/java/ZipInputStream
|
||||
IOUtils.copy(cis, NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzip the target file to byte array.
|
||||
*
|
||||
* @param sourceFile target file
|
||||
* @param checksum checksum
|
||||
* @return decompress byte array
|
||||
* @throws IOException IOException during decompress
|
||||
*/
|
||||
public static byte[] decompress(final String sourceFile, final Checksum checksum) throws IOException {
|
||||
byte[] result;
|
||||
try (final FileInputStream fis = new FileInputStream(sourceFile);
|
||||
final CheckedInputStream cis = new CheckedInputStream(fis, checksum);
|
||||
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(cis));
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
|
||||
while (zis.getNextEntry() != null) {
|
||||
IOUtils.copy(zis, bos);
|
||||
bos.flush();
|
||||
}
|
||||
IOUtils.copy(cis, NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
result = bos.toByteArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the lines in a <code>File</code>.
|
||||
* <p>
|
||||
* This method opens an <code>InputStream</code> for the file. When you have finished with the iterator you should
|
||||
* close the stream to free internal resources. This can be done by calling the {@link
|
||||
* org.apache.commons.io.LineIterator#close()} or {@link org.apache.commons.io.LineIterator#closeQuietly(org.apache.commons.io.LineIterator)}
|
||||
* method.
|
||||
* </p>
|
||||
* The recommended usage pattern is:
|
||||
* <pre>
|
||||
* LineIterator it = FileUtils.lineIterator(file, "UTF-8");
|
||||
* try {
|
||||
* while (it.hasNext()) {
|
||||
* String line = it.nextLine();
|
||||
* /// do something with line
|
||||
* }
|
||||
* } finally {
|
||||
* LineIterator.closeQuietly(iterator);
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* If an exception occurs during the creation of the iterator, the underlying stream is closed.
|
||||
* </p>
|
||||
*
|
||||
* @param file the file to open for input, must not be <code>null</code>
|
||||
* @param encoding the encoding to use, <code>null</code> means platform default
|
||||
* @return an Iterator of the lines in the file, never <code>null</code>
|
||||
* @throws IOException in case of an I/O error (file closed)
|
||||
* @since 1.2
|
||||
*/
|
||||
public static LineIterator lineIterator(File file, String encoding) throws IOException {
|
||||
return new LineIterator(FileUtils.lineIterator(file, encoding));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the lines in a <code>File</code> using the default encoding for the VM.
|
||||
*
|
||||
* @param file the file to open for input, must not be <code>null</code>
|
||||
* @return an Iterator of the lines in the file, never <code>null</code>
|
||||
* @throws IOException in case of an I/O error (file closed)
|
||||
* @see #lineIterator(File, String)
|
||||
* @since 1.3
|
||||
*/
|
||||
public static LineIterator lineIterator(File file) throws IOException {
|
||||
return new LineIterator(FileUtils.lineIterator(file, null));
|
||||
}
|
||||
|
||||
public static class LineIterator implements AutoCloseable {
|
||||
|
||||
private final org.apache.commons.io.LineIterator target;
|
||||
|
||||
/**
|
||||
* Constructs an iterator of the lines for a <code>Reader</code>.
|
||||
*
|
||||
* @param target {@link org.apache.commons.io.LineIterator}
|
||||
*/
|
||||
LineIterator(org.apache.commons.io.LineIterator target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return target.hasNext();
|
||||
}
|
||||
|
||||
public String next() {
|
||||
return target.next();
|
||||
}
|
||||
|
||||
public String nextLine() {
|
||||
return target.nextLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
target.close();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
target.remove();
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super String> action) {
|
||||
target.forEachRemaining(action);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.nacos.plugin.control.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Control plugin env utils.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class EnvUtils {
|
||||
|
||||
public static final String NACOS_HOME_KEY = "nacos.home";
|
||||
|
||||
private static final String NACOS_HOME_PROPERTY = "user.home";
|
||||
|
||||
private static final String NACOS_HOME_ADDITIONAL_FILEPATH = "nacos";
|
||||
|
||||
private static String nacosHomePath = null;
|
||||
|
||||
public static String getNacosHome() {
|
||||
if (StringUtils.isBlank(nacosHomePath)) {
|
||||
String nacosHome = System.getProperty(NACOS_HOME_KEY);
|
||||
if (StringUtils.isBlank(nacosHome)) {
|
||||
nacosHome = Paths.get(System.getProperty(NACOS_HOME_PROPERTY), NACOS_HOME_ADDITIONAL_FILEPATH)
|
||||
.toString();
|
||||
}
|
||||
return nacosHome;
|
||||
}
|
||||
return nacosHomePath;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 1999-2024 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.nacos.plugin.control;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.connection.ConnectionControlManager;
|
||||
import com.alibaba.nacos.plugin.control.connection.request.ConnectionCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.connection.response.ConnectionCheckCode;
|
||||
import com.alibaba.nacos.plugin.control.connection.response.ConnectionCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
import com.alibaba.nacos.plugin.control.spi.ControlManagerBuilder;
|
||||
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.TpsBarrier;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.TpsCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsResultCode;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ControlManagerBuilderTest implements ControlManagerBuilder {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionControlManager buildConnectionControlManager() {
|
||||
return new ConnectionControlManager() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "testConnection";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyConnectionLimitRule(ConnectionControlRule connectionControlRule) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionCheckResponse check(ConnectionCheckRequest connectionCheckRequest) {
|
||||
ConnectionCheckResponse connectionCheckResponse = new ConnectionCheckResponse();
|
||||
connectionCheckResponse.setSuccess(true);
|
||||
connectionCheckResponse.setCode(ConnectionCheckCode.PASS_BY_TOTAL);
|
||||
return connectionCheckResponse;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public TpsControlManager buildTpsControlManager() {
|
||||
return new TpsControlManager() {
|
||||
|
||||
@Override
|
||||
public void registerTpsPoint(String pointName) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TpsBarrier> getPoints() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TpsControlRule> getRules() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTpsRule(String pointName, TpsControlRule rule) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TpsCheckResponse check(TpsCheckRequest tpsRequest) {
|
||||
return new TpsCheckResponse(true, TpsResultCode.CHECK_SKIP, "skip");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "testTps";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright 1999-2024 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.nacos.plugin.control;
|
||||
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.plugin.control.configs.ControlConfigs;
|
||||
import com.alibaba.nacos.plugin.control.connection.ConnectionControlManager;
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.RuleStorageProxy;
|
||||
import com.alibaba.nacos.plugin.control.tps.MonitorType;
|
||||
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.RuleDetail;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
import com.alibaba.nacos.plugin.control.utils.EnvUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ControlManagerCenterTest {
|
||||
|
||||
@Before
|
||||
public void initInstance() throws NoSuchFieldException, IllegalAccessException {
|
||||
//reset instance for reload spi
|
||||
Field instanceControlConfigs = ControlConfigs.class.getDeclaredField("instance");
|
||||
instanceControlConfigs.setAccessible(true);
|
||||
instanceControlConfigs.set(null, null);
|
||||
Field instanceControlManagerCenter = ControlManagerCenter.class.getDeclaredField("instance");
|
||||
instanceControlManagerCenter.setAccessible(true);
|
||||
instanceControlManagerCenter.set(null, null);
|
||||
}
|
||||
|
||||
private void resetRuleStorageProxy() {
|
||||
try {
|
||||
//reset instance for reload spi
|
||||
Field instanceRuleStorageProxy = RuleStorageProxy.class.getDeclaredField("INSTANCE");
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(instanceRuleStorageProxy, instanceRuleStorageProxy.getModifiers() & ~Modifier.FINAL);
|
||||
instanceRuleStorageProxy.setAccessible(true);
|
||||
Constructor<RuleStorageProxy> constructor = RuleStorageProxy.class.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
Field modifiersFieldConstructor = Constructor.class.getDeclaredField("modifiers");
|
||||
modifiersFieldConstructor.setAccessible(true);
|
||||
modifiersFieldConstructor.setInt(constructor, constructor.getModifiers() & ~Modifier.PRIVATE);
|
||||
instanceRuleStorageProxy.set(null, constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInstance() {
|
||||
ControlConfigs.getInstance().setControlManagerType("test");
|
||||
ControlManagerCenter controlManagerCenter = ControlManagerCenter.getInstance();
|
||||
ConnectionControlManager connectionControlManager = controlManagerCenter.getConnectionControlManager();
|
||||
Assert.assertEquals("testConnection", connectionControlManager.getName());
|
||||
TpsControlManager tpsControlManager = controlManagerCenter.getTpsControlManager();
|
||||
Assert.assertEquals("testTps", tpsControlManager.getName());
|
||||
Assert.assertNotNull(controlManagerCenter.getRuleStorageProxy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInstanceWithDefault() {
|
||||
ControlManagerCenter controlManagerCenter = ControlManagerCenter.getInstance();
|
||||
ConnectionControlManager connectionControlManager = controlManagerCenter.getConnectionControlManager();
|
||||
Assert.assertEquals("noLimit", connectionControlManager.getName());
|
||||
TpsControlManager tpsControlManager = controlManagerCenter.getTpsControlManager();
|
||||
Assert.assertEquals("noLimit", tpsControlManager.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReloadTpsControlRule() throws Exception {
|
||||
String localRuleStorageBaseDir =
|
||||
EnvUtils.getNacosHome() + File.separator + "tmpTps" + File.separator + "tps" + File.separator;
|
||||
ControlConfigs.getInstance().setLocalRuleStorageBaseDir(localRuleStorageBaseDir);
|
||||
resetRuleStorageProxy();
|
||||
final ControlManagerCenter controlManagerCenter = ControlManagerCenter.getInstance();
|
||||
TpsControlRule tpsControlRule = new TpsControlRule();
|
||||
tpsControlRule.setPointName("test");
|
||||
RuleDetail ruleDetail = new RuleDetail();
|
||||
ruleDetail.setMaxCount(100);
|
||||
ruleDetail.setRuleName("test");
|
||||
ruleDetail.setMonitorType(MonitorType.INTERCEPT.getType());
|
||||
ruleDetail.setPeriod(TimeUnit.SECONDS);
|
||||
tpsControlRule.setPointRule(ruleDetail);
|
||||
String ruleContent = JacksonUtils.toJson(tpsControlRule);
|
||||
controlManagerCenter.getRuleStorageProxy().getLocalDiskStorage().saveTpsRule("test", ruleContent);
|
||||
controlManagerCenter.getTpsControlManager().applyTpsRule("test", tpsControlRule);
|
||||
TpsControlRule testTpsControlRule = controlManagerCenter.getTpsControlManager().getRules().get("test");
|
||||
|
||||
Assert.assertEquals(100, testTpsControlRule.getPointRule().getMaxCount());
|
||||
Assert.assertEquals("test", testTpsControlRule.getPointRule().getRuleName());
|
||||
|
||||
TpsControlRule tpsControlRule2 = new TpsControlRule();
|
||||
tpsControlRule2.setPointName("test");
|
||||
RuleDetail ruleDetail2 = new RuleDetail();
|
||||
ruleDetail2.setMaxCount(200);
|
||||
ruleDetail2.setRuleName("test2");
|
||||
ruleDetail2.setMonitorType(MonitorType.INTERCEPT.getType());
|
||||
ruleDetail2.setPeriod(TimeUnit.SECONDS);
|
||||
tpsControlRule2.setPointRule(ruleDetail2);
|
||||
String ruleContent2 = JacksonUtils.toJson(tpsControlRule2);
|
||||
controlManagerCenter.getRuleStorageProxy().getLocalDiskStorage().saveTpsRule("test", ruleContent2);
|
||||
controlManagerCenter.reloadTpsControlRule("test", false);
|
||||
|
||||
//wait event
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
TpsControlRule testTpsControlRule2 = controlManagerCenter.getTpsControlManager().getRules().get("test");
|
||||
Assert.assertEquals(200, testTpsControlRule2.getPointRule().getMaxCount());
|
||||
Assert.assertEquals("test2", testTpsControlRule2.getPointRule().getRuleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReloadTpsControlRuleExternal() throws Exception {
|
||||
String localRuleStorageBaseDir =
|
||||
EnvUtils.getNacosHome() + File.separator + "tmpTps" + File.separator + "tpsExternal" + File.separator;
|
||||
ControlConfigs.getInstance().setLocalRuleStorageBaseDir(localRuleStorageBaseDir);
|
||||
ControlConfigs.getInstance().setRuleExternalStorage("test");
|
||||
resetRuleStorageProxy();
|
||||
final ControlManagerCenter controlManagerCenter = ControlManagerCenter.getInstance();
|
||||
|
||||
TpsControlRule tpsControlRule = new TpsControlRule();
|
||||
tpsControlRule.setPointName("test");
|
||||
RuleDetail ruleDetail = new RuleDetail();
|
||||
ruleDetail.setMaxCount(100);
|
||||
ruleDetail.setRuleName("test");
|
||||
ruleDetail.setMonitorType(MonitorType.INTERCEPT.getType());
|
||||
ruleDetail.setPeriod(TimeUnit.SECONDS);
|
||||
tpsControlRule.setPointRule(ruleDetail);
|
||||
String ruleContent = JacksonUtils.toJson(tpsControlRule);
|
||||
controlManagerCenter.getRuleStorageProxy().getExternalStorage().saveTpsRule("test", ruleContent);
|
||||
controlManagerCenter.getTpsControlManager().applyTpsRule("test", tpsControlRule);
|
||||
TpsControlRule testTpsControlRule = controlManagerCenter.getTpsControlManager().getRules().get("test");
|
||||
|
||||
Assert.assertEquals(100, testTpsControlRule.getPointRule().getMaxCount());
|
||||
Assert.assertEquals("test", testTpsControlRule.getPointRule().getRuleName());
|
||||
|
||||
TpsControlRule tpsControlRule2 = new TpsControlRule();
|
||||
tpsControlRule2.setPointName("test");
|
||||
RuleDetail ruleDetail2 = new RuleDetail();
|
||||
ruleDetail2.setMaxCount(200);
|
||||
ruleDetail2.setRuleName("test2");
|
||||
ruleDetail2.setMonitorType(MonitorType.INTERCEPT.getType());
|
||||
ruleDetail2.setPeriod(TimeUnit.SECONDS);
|
||||
tpsControlRule2.setPointRule(ruleDetail2);
|
||||
String ruleContent2 = JacksonUtils.toJson(tpsControlRule2);
|
||||
controlManagerCenter.getRuleStorageProxy().getExternalStorage().saveTpsRule("test", ruleContent2);
|
||||
controlManagerCenter.reloadTpsControlRule("test", true);
|
||||
|
||||
//wait event
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
TpsControlRule testTpsControlRule2 = controlManagerCenter.getTpsControlManager().getRules().get("test");
|
||||
Assert.assertEquals(200, testTpsControlRule2.getPointRule().getMaxCount());
|
||||
Assert.assertEquals("test2", testTpsControlRule2.getPointRule().getRuleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReloadConnectionControlRule() throws Exception {
|
||||
String localRuleStorageBaseDir =
|
||||
EnvUtils.getNacosHome() + File.separator + "tmpConnection" + File.separator + "connection"
|
||||
+ File.separator;
|
||||
ControlConfigs.getInstance().setLocalRuleStorageBaseDir(localRuleStorageBaseDir);
|
||||
resetRuleStorageProxy();
|
||||
ConnectionControlRule connectionLimitRule = new ConnectionControlRule();
|
||||
connectionLimitRule.setCountLimit(100);
|
||||
String ruleContent = JacksonUtils.toJson(connectionLimitRule);
|
||||
|
||||
ControlManagerCenter controlManagerCenter = ControlManagerCenter.getInstance();
|
||||
controlManagerCenter.getRuleStorageProxy().getLocalDiskStorage().saveConnectionRule(ruleContent);
|
||||
ConnectionControlManager connectionControlManager = controlManagerCenter.getConnectionControlManager();
|
||||
//apply rule
|
||||
connectionControlManager.applyConnectionLimitRule(connectionLimitRule);
|
||||
ConnectionControlRule connectionLimitRule1 = connectionControlManager.getConnectionLimitRule();
|
||||
Assert.assertEquals(100, connectionLimitRule1.getCountLimit());
|
||||
|
||||
ConnectionControlRule connectionLimitRule2 = new ConnectionControlRule();
|
||||
connectionLimitRule2.setCountLimit(200);
|
||||
String ruleContent2 = JacksonUtils.toJson(connectionLimitRule2);
|
||||
controlManagerCenter.getRuleStorageProxy().getLocalDiskStorage().saveConnectionRule(ruleContent2);
|
||||
//reload new rule
|
||||
controlManagerCenter.reloadConnectionControlRule(false);
|
||||
|
||||
//wait event
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
ConnectionControlRule connectionLimitRule3 = connectionControlManager.getConnectionLimitRule();
|
||||
Assert.assertEquals(200, connectionLimitRule3.getCountLimit());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReloadConnectionControlRuleExternal() throws Exception {
|
||||
String localRuleStorageBaseDir =
|
||||
EnvUtils.getNacosHome() + File.separator + "tmpConnection" + File.separator + "connectionExternal"
|
||||
+ File.separator;
|
||||
ControlConfigs.getInstance().setLocalRuleStorageBaseDir(localRuleStorageBaseDir);
|
||||
ControlConfigs.getInstance().setRuleExternalStorage("test");
|
||||
resetRuleStorageProxy();
|
||||
ConnectionControlRule connectionLimitRule = new ConnectionControlRule();
|
||||
connectionLimitRule.setCountLimit(100);
|
||||
String ruleContent = JacksonUtils.toJson(connectionLimitRule);
|
||||
|
||||
ControlManagerCenter controlManagerCenter = ControlManagerCenter.getInstance();
|
||||
controlManagerCenter.getRuleStorageProxy().getExternalStorage().saveConnectionRule(ruleContent);
|
||||
ConnectionControlManager connectionControlManager = controlManagerCenter.getConnectionControlManager();
|
||||
//apply rule
|
||||
connectionControlManager.applyConnectionLimitRule(connectionLimitRule);
|
||||
ConnectionControlRule connectionLimitRule1 = connectionControlManager.getConnectionLimitRule();
|
||||
Assert.assertEquals(100, connectionLimitRule1.getCountLimit());
|
||||
|
||||
ConnectionControlRule connectionLimitRule2 = new ConnectionControlRule();
|
||||
connectionLimitRule2.setCountLimit(200);
|
||||
String ruleContent2 = JacksonUtils.toJson(connectionLimitRule2);
|
||||
controlManagerCenter.getRuleStorageProxy().getExternalStorage().saveConnectionRule(ruleContent2);
|
||||
//reload new rule
|
||||
controlManagerCenter.reloadConnectionControlRule(true);
|
||||
|
||||
//wait event
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
ConnectionControlRule connectionLimitRule3 = connectionControlManager.getConnectionLimitRule();
|
||||
Assert.assertEquals(200, connectionLimitRule3.getCountLimit());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.connection.request.ConnectionCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.connection.response.ConnectionCheckCode;
|
||||
import com.alibaba.nacos.plugin.control.connection.response.ConnectionCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.connection.rule.ConnectionControlRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* two fixed metrics, total 30, iptotal 15, detail is testa(total-20,iptotal-10),testb(total-10,iptotal-5).
|
||||
*/
|
||||
public class DefaultConnectionControlManagerTest {
|
||||
|
||||
DefaultConnectionControlManager connectionControlManager = new DefaultConnectionControlManager();
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
ConnectionControlRule connectionControlRule = new ConnectionControlRule();
|
||||
|
||||
ConnectionCheckRequest connectionCheckRequest = new ConnectionCheckRequest("127.0.0.1", "test", "sdk");
|
||||
ConnectionCheckResponse check = connectionControlManager.check(connectionCheckRequest);
|
||||
connectionControlRule.setCountLimit(40);
|
||||
connectionControlManager.applyConnectionLimitRule(connectionControlRule);
|
||||
check = connectionControlManager.check(connectionCheckRequest);
|
||||
Assert.assertTrue(check.isSuccess());
|
||||
Assert.assertEquals(ConnectionCheckCode.CHECK_SKIP, check.getCode());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection;
|
||||
|
||||
public class TestAConnectionMetricsCollector implements ConnectionMetricsCollector {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "testa";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalCount() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCountForIp(String ip) {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.connection;
|
||||
|
||||
public class TestBConnectionMetricsCollector implements ConnectionMetricsCollector {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "testb";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalCount() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCountForIp(String ip) {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 1999-2024 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.nacos.plugin.control.spi;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.ExternalRuleStorage;
|
||||
|
||||
public class ExternalRuleStorageBuilderTest implements ExternalRuleStorageBuilder {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalRuleStorage buildExternalRuleStorage() {
|
||||
return new ExternalRuleStorageTest();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 1999-2024 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.nacos.plugin.control.spi;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.rule.storage.ExternalRuleStorage;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExternalRuleStorageTest implements ExternalRuleStorage {
|
||||
|
||||
private String ruleContent;
|
||||
|
||||
private Map<String, String> tpsRuleMap = new HashMap<>(1);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "testExternal";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConnectionRule(String ruleContent) throws Exception {
|
||||
this.ruleContent = ruleContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionRule() {
|
||||
return ruleContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveTpsRule(String pointName, String ruleContent) throws Exception {
|
||||
tpsRuleMap.put(pointName, ruleContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTpsRule(String pointName) {
|
||||
return tpsRuleMap.get(pointName);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.nacos.plugin.control.tps;
|
||||
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.TpsBarrier;
|
||||
import com.alibaba.nacos.plugin.control.tps.barrier.DefaultNacosTpsBarrier;
|
||||
import com.alibaba.nacos.plugin.control.tps.request.TpsCheckRequest;
|
||||
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.RuleDetail;
|
||||
import com.alibaba.nacos.plugin.control.tps.rule.TpsControlRule;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class DefaultNacosTpsBarrierTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalPointPassAndDeny() {
|
||||
String testTpsBarrier = "test_barrier";
|
||||
|
||||
// max 5tps
|
||||
TpsControlRule tpsControlRule = new TpsControlRule();
|
||||
tpsControlRule.setPointName(testTpsBarrier);
|
||||
RuleDetail ruleDetail = new RuleDetail();
|
||||
ruleDetail.setMaxCount(5);
|
||||
ruleDetail.setMonitorType(MonitorType.INTERCEPT.getType());
|
||||
ruleDetail.setPeriod(TimeUnit.SECONDS);
|
||||
tpsControlRule.setPointRule(ruleDetail);
|
||||
|
||||
TpsBarrier tpsBarrier = new DefaultNacosTpsBarrier(testTpsBarrier);
|
||||
tpsBarrier.applyRule(tpsControlRule);
|
||||
|
||||
//test point keys
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
TpsCheckRequest tpsCheckRequest = new TpsCheckRequest();
|
||||
tpsCheckRequest.setTimestamp(timeMillis);
|
||||
|
||||
// 5tps check pass
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TpsCheckResponse tpsCheckResponse = tpsBarrier.applyTps(tpsCheckRequest);
|
||||
Assert.assertTrue(tpsCheckResponse.isSuccess());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright 1999-2024 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.nacos.plugin.control.utils;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DiskUtilsTest {
|
||||
private static File testFile;
|
||||
|
||||
private static final String TMP_PATH = EnvUtils.getNacosHome() + File.separator + "data" + File.separator + "tmp" + File.separator;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() throws IOException {
|
||||
testFile = DiskUtils.createTmpFile("nacostmp", ".ut");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() throws IOException {
|
||||
testFile.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTouch() throws IOException {
|
||||
File file = Paths.get(TMP_PATH, "touch.ut").toFile();
|
||||
Assert.assertFalse(file.exists());
|
||||
DiskUtils.touch(file);
|
||||
Assert.assertTrue(file.exists());
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTouchWithFileName() throws IOException {
|
||||
File file = Paths.get(TMP_PATH, UUID.randomUUID().toString()).toFile();
|
||||
Assert.assertFalse(file.exists());
|
||||
DiskUtils.touch(file.getParent(), file.getName());
|
||||
Assert.assertTrue(file.exists());
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTmpFile() throws IOException {
|
||||
File tmpFile = null;
|
||||
try {
|
||||
tmpFile = DiskUtils.createTmpFile("nacos1", ".ut");
|
||||
Assert.assertTrue(tmpFile.getName().startsWith("nacos1"));
|
||||
Assert.assertTrue(tmpFile.getName().endsWith(".ut"));
|
||||
} finally {
|
||||
if (tmpFile != null) {
|
||||
tmpFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTmpFileWithPath() throws IOException {
|
||||
File tmpFile = null;
|
||||
try {
|
||||
tmpFile = DiskUtils.createTmpFile(TMP_PATH, "nacos1", ".ut");
|
||||
Assert.assertEquals(TMP_PATH, tmpFile.getParent() + File.separator);
|
||||
Assert.assertTrue(tmpFile.getName().startsWith("nacos1"));
|
||||
Assert.assertTrue(tmpFile.getName().endsWith(".ut"));
|
||||
} finally {
|
||||
if (tmpFile != null) {
|
||||
tmpFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFile() {
|
||||
Assert.assertNotNull(DiskUtils.readFile(testFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileWithInputStream() throws FileNotFoundException {
|
||||
Assert.assertNotNull(DiskUtils.readFile(new FileInputStream(testFile)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileWithPath() {
|
||||
Assert.assertNotNull(DiskUtils.readFile(testFile.getParent(), testFile.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileBytes() {
|
||||
Assert.assertNotNull(DiskUtils.readFileBytes(testFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileBytesWithPath() {
|
||||
Assert.assertNotNull(DiskUtils.readFileBytes(testFile.getParent(), testFile.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeFile() {
|
||||
Assert.assertTrue(DiskUtils.writeFile(testFile, "unit test".getBytes(StandardCharsets.UTF_8), false));
|
||||
Assert.assertEquals("unit test", DiskUtils.readFile(testFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteQuietly() throws IOException {
|
||||
File tmpFile = DiskUtils.createTmpFile(UUID.randomUUID().toString(), ".ut");
|
||||
DiskUtils.deleteQuietly(tmpFile);
|
||||
Assert.assertFalse(tmpFile.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteQuietlyWithPath() throws IOException {
|
||||
String dir = TMP_PATH + "/" + "diskutils";
|
||||
DiskUtils.forceMkdir(dir);
|
||||
DiskUtils.createTmpFile(dir, "nacos", ".ut");
|
||||
Path path = Paths.get(dir);
|
||||
DiskUtils.deleteQuietly(path);
|
||||
|
||||
Assert.assertFalse(path.toFile().exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFile() throws IOException {
|
||||
File tmpFile = DiskUtils.createTmpFile(UUID.randomUUID().toString(), ".ut");
|
||||
Assert.assertTrue(DiskUtils.deleteFile(tmpFile.getParent(), tmpFile.getName()));
|
||||
Assert.assertFalse(DiskUtils.deleteFile(tmpFile.getParent(), tmpFile.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteDirectory() throws IOException {
|
||||
Path diskutils = Paths.get(TMP_PATH, "diskutils");
|
||||
File file = diskutils.toFile();
|
||||
if (!file.exists()) {
|
||||
file.mkdir();
|
||||
}
|
||||
|
||||
Assert.assertTrue(file.exists());
|
||||
DiskUtils.deleteDirectory(diskutils.toString());
|
||||
Assert.assertFalse(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceMkdir() throws IOException {
|
||||
File dir = Paths.get(TMP_PATH, UUID.randomUUID().toString(), UUID.randomUUID().toString())
|
||||
.toFile();
|
||||
DiskUtils.forceMkdir(dir);
|
||||
Assert.assertTrue(dir.exists());
|
||||
dir.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceMkdirWithPath() throws IOException {
|
||||
Path path = Paths.get(TMP_PATH, UUID.randomUUID().toString(), UUID.randomUUID().toString());
|
||||
DiskUtils.forceMkdir(path.toString());
|
||||
File file = path.toFile();
|
||||
Assert.assertTrue(file.exists());
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteDirThenMkdir() throws IOException {
|
||||
Path path = Paths.get(TMP_PATH, UUID.randomUUID().toString());
|
||||
DiskUtils.forceMkdir(path.toString());
|
||||
|
||||
DiskUtils.createTmpFile(path.toString(), UUID.randomUUID().toString(), ".ut");
|
||||
DiskUtils.createTmpFile(path.toString(), UUID.randomUUID().toString(), ".ut");
|
||||
|
||||
DiskUtils.deleteDirThenMkdir(path.toString());
|
||||
|
||||
File file = path.toFile();
|
||||
Assert.assertTrue(file.exists());
|
||||
Assert.assertTrue(file.isDirectory());
|
||||
Assert.assertTrue(file.list() == null || file.list().length == 0);
|
||||
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyDirectory() throws IOException {
|
||||
Path srcPath = Paths.get(TMP_PATH, UUID.randomUUID().toString());
|
||||
DiskUtils.forceMkdir(srcPath.toString());
|
||||
File nacos = DiskUtils.createTmpFile(srcPath.toString(), "nacos", ".ut");
|
||||
|
||||
Path destPath = Paths.get(TMP_PATH, UUID.randomUUID().toString());
|
||||
DiskUtils.copyDirectory(srcPath.toFile(), destPath.toFile());
|
||||
|
||||
File file = Paths.get(destPath.toString(), nacos.getName()).toFile();
|
||||
Assert.assertTrue(file.exists());
|
||||
|
||||
DiskUtils.deleteDirectory(srcPath.toString());
|
||||
DiskUtils.deleteDirectory(destPath.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFile() throws IOException {
|
||||
File nacos = DiskUtils.createTmpFile("nacos", ".ut");
|
||||
DiskUtils.copyFile(testFile, nacos);
|
||||
|
||||
Assert.assertEquals(DiskUtils.readFile(testFile), DiskUtils.readFile(nacos));
|
||||
|
||||
nacos.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void openFile() {
|
||||
File file = DiskUtils.openFile(testFile.getParent(), testFile.getName());
|
||||
Assert.assertNotNull(file);
|
||||
Assert.assertEquals(testFile.getPath(), file.getPath());
|
||||
Assert.assertEquals(testFile.getName(), file.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenFileWithPath() {
|
||||
File file = DiskUtils.openFile(testFile.getParent(), testFile.getName(), false);
|
||||
Assert.assertNotNull(file);
|
||||
Assert.assertEquals(testFile.getPath(), file.getPath());
|
||||
Assert.assertEquals(testFile.getName(), file.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 1999-2024 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.nacos.plugin.control.utils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class EnvUtilsTest {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.clearProperty("nacos.home");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String nacosHome = EnvUtils.getNacosHome();
|
||||
Assert.assertEquals(System.getProperty("user.home") + File.separator + "nacos", nacosHome);
|
||||
|
||||
System.setProperty("nacos.home", "test");
|
||||
String testHome = EnvUtils.getNacosHome();
|
||||
Assert.assertEquals("test", testHome);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright 1999-2020 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.
|
||||
#
|
||||
|
||||
#
|
||||
#
|
||||
# Copyright 1999-2021 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.
|
||||
#
|
||||
#
|
||||
|
||||
com.alibaba.nacos.plugin.control.connection.TestAConnectionMetricsCollector
|
||||
com.alibaba.nacos.plugin.control.connection.TestBConnectionMetricsCollector
|
||||
@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright 1999-2024 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.
|
||||
#
|
||||
|
||||
com.alibaba.nacos.plugin.control.ControlManagerBuilderTest
|
||||
@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright 1999-2024 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.
|
||||
#
|
||||
|
||||
com.alibaba.nacos.plugin.control.spi.ExternalRuleStorageBuilderTest
|
||||
@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright 1999-2020 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.
|
||||
#
|
||||
|
||||
#
|
||||
#
|
||||
# Copyright 1999-2021 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.
|
||||
#
|
||||
#
|
||||
|
||||
com.alibaba.nacos.plugin.control.tps.barrier.creator.LocalSimpleCountBarrierCreator
|
||||
Reference in New Issue
Block a user