Separate parameter metric storage from ParamFlowSlot and improve ParamFlowRuleUtil
- Add a ParameterMetricStorage specific for caching ParameterMetric (moved from ParamSlot) - Add rule map building helper method in ParamFlowRuleUtil so that we can reuse it in other rule managers Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
54da16d304
commit
77dec5f845
|
|
@ -43,9 +43,9 @@ import com.alibaba.csp.sentinel.util.TimeUtil;
|
|||
* @author Eric Zhao
|
||||
* @since 0.2.0
|
||||
*/
|
||||
final class ParamFlowChecker {
|
||||
public final class ParamFlowChecker {
|
||||
|
||||
static boolean passCheck(ResourceWrapper resourceWrapper, /*@Valid*/ ParamFlowRule rule, /*@Valid*/ int count,
|
||||
public static boolean passCheck(ResourceWrapper resourceWrapper, /*@Valid*/ ParamFlowRule rule, /*@Valid*/ int count,
|
||||
Object... args) {
|
||||
if (args == null) {
|
||||
return true;
|
||||
|
|
@ -249,7 +249,7 @@ final class ParamFlowChecker {
|
|||
|
||||
private static ParameterMetric getParameterMetric(ResourceWrapper resourceWrapper) {
|
||||
// Should not be null.
|
||||
return ParamFlowSlot.getParamMetric(resourceWrapper);
|
||||
return ParameterMetricStorage.getParamMetric(resourceWrapper);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -26,9 +25,7 @@ import com.alibaba.csp.sentinel.log.RecordLog;
|
|||
import com.alibaba.csp.sentinel.property.DynamicSentinelProperty;
|
||||
import com.alibaba.csp.sentinel.property.PropertyListener;
|
||||
import com.alibaba.csp.sentinel.property.SentinelProperty;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Manager for frequent ("hot-spot") parameter flow rules.
|
||||
|
|
@ -39,7 +36,7 @@ import com.alibaba.csp.sentinel.util.StringUtil;
|
|||
*/
|
||||
public final class ParamFlowRuleManager {
|
||||
|
||||
private static final Map<String, Set<ParamFlowRule>> paramFlowRules = new ConcurrentHashMap<>();
|
||||
private static final Map<String, List<ParamFlowRule>> paramFlowRules = new ConcurrentHashMap<>();
|
||||
|
||||
private final static RulePropertyListener PROPERTY_LISTENER = new RulePropertyListener();
|
||||
private static SentinelProperty<List<ParamFlowRule>> currentProperty = new DynamicSentinelProperty<>();
|
||||
|
|
@ -83,7 +80,7 @@ public final class ParamFlowRuleManager {
|
|||
}
|
||||
|
||||
public static boolean hasRules(String resourceName) {
|
||||
Set<ParamFlowRule> rules = paramFlowRules.get(resourceName);
|
||||
List<ParamFlowRule> rules = paramFlowRules.get(resourceName);
|
||||
return rules != null && !rules.isEmpty();
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +91,7 @@ public final class ParamFlowRuleManager {
|
|||
*/
|
||||
public static List<ParamFlowRule> getRules() {
|
||||
List<ParamFlowRule> rules = new ArrayList<>();
|
||||
for (Map.Entry<String, Set<ParamFlowRule>> entry : paramFlowRules.entrySet()) {
|
||||
for (Map.Entry<String, List<ParamFlowRule>> entry : paramFlowRules.entrySet()) {
|
||||
rules.addAll(entry.getValue());
|
||||
}
|
||||
return rules;
|
||||
|
|
@ -104,61 +101,38 @@ public final class ParamFlowRuleManager {
|
|||
|
||||
@Override
|
||||
public void configUpdate(List<ParamFlowRule> list) {
|
||||
Map<String, Set<ParamFlowRule>> rules = aggregateHotParamRules(list);
|
||||
Map<String, List<ParamFlowRule>> rules = aggregateAndPrepareParamRules(list);
|
||||
if (rules != null) {
|
||||
paramFlowRules.clear();
|
||||
paramFlowRules.putAll(rules);
|
||||
}
|
||||
RecordLog.info("[ParamFlowRuleManager] Hot spot parameter flow rules received: " + paramFlowRules);
|
||||
RecordLog.info("[ParamFlowRuleManager] Parameter flow rules received: " + paramFlowRules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configLoad(List<ParamFlowRule> list) {
|
||||
Map<String, Set<ParamFlowRule>> rules = aggregateHotParamRules(list);
|
||||
Map<String, List<ParamFlowRule>> rules = aggregateAndPrepareParamRules(list);
|
||||
if (rules != null) {
|
||||
paramFlowRules.clear();
|
||||
paramFlowRules.putAll(rules);
|
||||
}
|
||||
RecordLog.info("[ParamFlowRuleManager] Hot spot parameter flow rules received: " + paramFlowRules);
|
||||
RecordLog.info("[ParamFlowRuleManager] Parameter flow rules received: " + paramFlowRules);
|
||||
}
|
||||
|
||||
private Map<String, Set<ParamFlowRule>> aggregateHotParamRules(List<ParamFlowRule> list) {
|
||||
Map<String, Set<ParamFlowRule>> newRuleMap = new ConcurrentHashMap<>();
|
||||
|
||||
if (list == null || list.isEmpty()) {
|
||||
private Map<String, List<ParamFlowRule>> aggregateAndPrepareParamRules(List<ParamFlowRule> list) {
|
||||
Map<String, List<ParamFlowRule>> newRuleMap = ParamFlowRuleUtil.buildParamRuleMap(list);
|
||||
if (newRuleMap == null || newRuleMap.isEmpty()) {
|
||||
// No parameter flow rules, so clear all the metrics.
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
RecordLog.info("[ParamFlowRuleManager] No parameter flow rules, clearing all parameter metrics");
|
||||
return newRuleMap;
|
||||
}
|
||||
|
||||
for (ParamFlowRule rule : list) {
|
||||
if (!ParamFlowRuleUtil.isValidRule(rule)) {
|
||||
RecordLog.warn("[ParamFlowRuleManager] Ignoring invalid rule when loading new rules: " + rule);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StringUtil.isBlank(rule.getLimitApp())) {
|
||||
rule.setLimitApp(RuleConstant.LIMIT_APP_DEFAULT);
|
||||
}
|
||||
|
||||
ParamFlowRuleUtil.fillExceptionFlowItems(rule);
|
||||
|
||||
String resourceName = rule.getResource();
|
||||
Set<ParamFlowRule> ruleSet = newRuleMap.get(resourceName);
|
||||
if (ruleSet == null) {
|
||||
ruleSet = new HashSet<>();
|
||||
newRuleMap.put(resourceName, ruleSet);
|
||||
}
|
||||
|
||||
ruleSet.add(rule);
|
||||
}
|
||||
|
||||
// Clear unused hot param metrics.
|
||||
// Clear unused parameter metrics.
|
||||
Set<String> previousResources = paramFlowRules.keySet();
|
||||
for (String resource : previousResources) {
|
||||
if (!newRuleMap.containsKey(resource)) {
|
||||
ParamFlowSlot.clearHotParamMetricForName(resource);
|
||||
ParameterMetricStorage.clearParamMetricForResource(resource);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,6 +140,5 @@ public final class ParamFlowRuleManager {
|
|||
}
|
||||
}
|
||||
|
||||
private ParamFlowRuleManager() {
|
||||
}
|
||||
private ParamFlowRuleManager() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,18 +17,32 @@ package com.alibaba.csp.sentinel.slots.block.flow.param;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleUtil;
|
||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
import com.alibaba.csp.sentinel.util.function.Function;
|
||||
import com.alibaba.csp.sentinel.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public final class ParamFlowRuleUtil {
|
||||
|
||||
/**
|
||||
* Check whether the provided rule is valid.
|
||||
*
|
||||
* @param rule any parameter rule
|
||||
* @return true if valid, otherwise false
|
||||
*/
|
||||
public static boolean isValidRule(ParamFlowRule rule) {
|
||||
return rule != null && !StringUtil.isBlank(rule.getResource()) && rule.getCount() >= 0
|
||||
&& rule.getGrade() >= 0 && rule.getParamIdx() != null
|
||||
|
|
@ -55,6 +69,11 @@ public final class ParamFlowRuleUtil {
|
|||
return id != null && id > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the parameter rule with parsed items.
|
||||
*
|
||||
* @param rule valid parameter rule
|
||||
*/
|
||||
public static void fillExceptionFlowItems(ParamFlowRule rule) {
|
||||
if (rule != null) {
|
||||
if (rule.getParamFlowItemList() == null) {
|
||||
|
|
@ -66,11 +85,111 @@ public final class ParamFlowRuleUtil {
|
|||
}
|
||||
}
|
||||
|
||||
static Map<Object, Integer> parseHotItems(List<ParamFlowItem> items) {
|
||||
Map<Object, Integer> itemMap = new HashMap<Object, Integer>();
|
||||
if (items == null || items.isEmpty()) {
|
||||
return itemMap;
|
||||
/**
|
||||
* Build the flow rule map from raw list of flow rules, grouping by resource name.
|
||||
*
|
||||
* @param list raw list of flow rules
|
||||
* @return constructed new flow rule map; empty map if list is null or empty, or no valid rules
|
||||
* @since 1.6.1
|
||||
*/
|
||||
public static Map<String, List<ParamFlowRule>> buildParamRuleMap(List<ParamFlowRule> list) {
|
||||
return buildParamRuleMap(list, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the parameter flow rule map from raw list of rules, grouping by resource name.
|
||||
*
|
||||
* @param list raw list of parameter flow rules
|
||||
* @param filter rule filter
|
||||
* @return constructed new parameter flow rule map; empty map if list is null or empty, or no wanted rules
|
||||
* @since 1.6.1
|
||||
*/
|
||||
public static Map<String, List<ParamFlowRule>> buildParamRuleMap(List<ParamFlowRule> list,
|
||||
Predicate<ParamFlowRule> filter) {
|
||||
return buildParamRuleMap(list, filter, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the parameter flow rule map from raw list of rules, grouping by resource name.
|
||||
*
|
||||
* @param list raw list of parameter flow rules
|
||||
* @param filter rule filter
|
||||
* @param shouldSort whether the rules should be sorted
|
||||
* @return constructed new parameter flow rule map; empty map if list is null or empty, or no wanted rules
|
||||
* @since 1.6.1
|
||||
*/
|
||||
public static Map<String, List<ParamFlowRule>> buildParamRuleMap(List<ParamFlowRule> list,
|
||||
Predicate<ParamFlowRule> filter,
|
||||
boolean shouldSort) {
|
||||
return buildParamRuleMap(list, EXTRACT_RESOURCE, filter, shouldSort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the rule map from raw list of parameter flow rules, grouping by provided group function.
|
||||
*
|
||||
* @param list raw list of parameter flow rules
|
||||
* @param groupFunction grouping function of the map (by key)
|
||||
* @param filter rule filter
|
||||
* @param shouldSort whether the rules should be sorted
|
||||
* @param <K> type of key
|
||||
* @return constructed new rule map; empty map if list is null or empty, or no wanted rules
|
||||
* @since 1.6.1
|
||||
*/
|
||||
public static <K> Map<K, List<ParamFlowRule>> buildParamRuleMap(List<ParamFlowRule> list,
|
||||
Function<ParamFlowRule, K> groupFunction,
|
||||
Predicate<ParamFlowRule> filter,
|
||||
boolean shouldSort) {
|
||||
AssertUtil.notNull(groupFunction, "groupFunction should not be null");
|
||||
Map<K, List<ParamFlowRule>> newRuleMap = new ConcurrentHashMap<>();
|
||||
if (list == null || list.isEmpty()) {
|
||||
return newRuleMap;
|
||||
}
|
||||
Map<K, Set<ParamFlowRule>> tmpMap = new ConcurrentHashMap<>();
|
||||
|
||||
for (ParamFlowRule rule : list) {
|
||||
if (!ParamFlowRuleUtil.isValidRule(rule)) {
|
||||
RecordLog.warn("[ParamFlowRuleManager] Ignoring invalid rule when loading new rules: " + rule);
|
||||
continue;
|
||||
}
|
||||
if (filter != null && !filter.test(rule)) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtil.isBlank(rule.getLimitApp())) {
|
||||
rule.setLimitApp(RuleConstant.LIMIT_APP_DEFAULT);
|
||||
}
|
||||
|
||||
ParamFlowRuleUtil.fillExceptionFlowItems(rule);
|
||||
|
||||
K key = groupFunction.apply(rule);
|
||||
if (key == null) {
|
||||
continue;
|
||||
}
|
||||
Set<ParamFlowRule> flowRules = tmpMap.get(key);
|
||||
|
||||
if (flowRules == null) {
|
||||
// Use hash set here to remove duplicate rules.
|
||||
flowRules = new HashSet<>();
|
||||
tmpMap.put(key, flowRules);
|
||||
}
|
||||
|
||||
flowRules.add(rule);
|
||||
}
|
||||
for (Entry<K, Set<ParamFlowRule>> entries : tmpMap.entrySet()) {
|
||||
List<ParamFlowRule> rules = new ArrayList<>(entries.getValue());
|
||||
if (shouldSort) {
|
||||
// TODO: Sort the rules.
|
||||
}
|
||||
newRuleMap.put(entries.getKey(), rules);
|
||||
}
|
||||
|
||||
return newRuleMap;
|
||||
}
|
||||
|
||||
static Map<Object, Integer> parseHotItems(List<ParamFlowItem> items) {
|
||||
if (items == null || items.isEmpty()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
Map<Object, Integer> itemMap = new HashMap<>(items.size());
|
||||
for (ParamFlowItem item : items) {
|
||||
// Value should not be null.
|
||||
Object value;
|
||||
|
|
@ -120,5 +239,12 @@ public final class ParamFlowRuleUtil {
|
|||
return value;
|
||||
}
|
||||
|
||||
private static final Function<ParamFlowRule, String> EXTRACT_RESOURCE = new Function<ParamFlowRule, String>() {
|
||||
@Override
|
||||
public String apply(ParamFlowRule rule) {
|
||||
return rule.getResource();
|
||||
}
|
||||
};
|
||||
|
||||
private ParamFlowRuleUtil() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,18 +16,12 @@
|
|||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.context.Context;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.node.DefaultNode;
|
||||
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
/**
|
||||
* A processor slot that is responsible for flow control by frequent ("hot spot") parameters.
|
||||
|
|
@ -38,13 +32,6 @@ import com.alibaba.csp.sentinel.util.StringUtil;
|
|||
*/
|
||||
public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
|
||||
private static final Map<ResourceWrapper, ParameterMetric> metricsMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Lock for a specific resource.
|
||||
*/
|
||||
private final Object LOCK = new Object();
|
||||
|
||||
@Override
|
||||
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,
|
||||
boolean prioritized, Object... args) throws Throwable {
|
||||
|
|
@ -68,7 +55,7 @@ public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
|||
if (-paramIdx <= length) {
|
||||
rule.setParamIdx(length + paramIdx);
|
||||
} else {
|
||||
// illegal index, give it a illegal positive value, latter rule check will pass
|
||||
// Illegal index, give it a illegal positive value, latter rule checking will pass.
|
||||
rule.setParamIdx(-paramIdx);
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +74,7 @@ public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
|||
applyRealParamIdx(rule, args.length);
|
||||
|
||||
// Initialize the parameter metrics.
|
||||
initHotParamMetricsFor(resourceWrapper, rule);
|
||||
ParameterMetricStorage.initParamMetricsFor(resourceWrapper, rule);
|
||||
|
||||
if (!ParamFlowChecker.passCheck(resourceWrapper, rule, count, args)) {
|
||||
String triggeredParam = "";
|
||||
|
|
@ -99,60 +86,4 @@ public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the parameter metric and index map for given resource.
|
||||
* Package-private for test.
|
||||
*
|
||||
* @param resourceWrapper resource to init
|
||||
* @param rule relevant rule
|
||||
*/
|
||||
void initHotParamMetricsFor(ResourceWrapper resourceWrapper, /*@Valid*/ ParamFlowRule rule) {
|
||||
ParameterMetric metric;
|
||||
// Assume that the resource is valid.
|
||||
if ((metric = metricsMap.get(resourceWrapper)) == null) {
|
||||
synchronized (LOCK) {
|
||||
if ((metric = metricsMap.get(resourceWrapper)) == null) {
|
||||
metric = new ParameterMetric();
|
||||
metricsMap.put(resourceWrapper, metric);
|
||||
RecordLog.info("[ParamFlowSlot] Creating parameter metric for: " + resourceWrapper.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
metric.initialize(rule);
|
||||
}
|
||||
|
||||
public static ParameterMetric getParamMetric(ResourceWrapper resourceWrapper) {
|
||||
if (resourceWrapper == null || resourceWrapper.getName() == null) {
|
||||
return null;
|
||||
}
|
||||
return metricsMap.get(resourceWrapper);
|
||||
}
|
||||
|
||||
public static ParameterMetric getHotParamMetricForName(String resourceName) {
|
||||
if (StringUtil.isBlank(resourceName)) {
|
||||
return null;
|
||||
}
|
||||
for (EntryType nodeType : EntryType.values()) {
|
||||
ParameterMetric metric = metricsMap.get(new StringResourceWrapper(resourceName, nodeType));
|
||||
if (metric != null) {
|
||||
return metric;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void clearHotParamMetricForName(String resourceName) {
|
||||
if (StringUtil.isBlank(resourceName)) {
|
||||
return;
|
||||
}
|
||||
for (EntryType nodeType : EntryType.values()) {
|
||||
metricsMap.remove(new StringResourceWrapper(resourceName, nodeType));
|
||||
}
|
||||
RecordLog.info("[ParamFlowSlot] Clearing parameter metric for: " + resourceName);
|
||||
}
|
||||
|
||||
static Map<ResourceWrapper, ParameterMetric> getMetricsMap() {
|
||||
return metricsMap;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 1999-2019 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
* @since 1.6.1
|
||||
*/
|
||||
public final class ParameterMetricStorage {
|
||||
|
||||
private static final Map<String, ParameterMetric> metricsMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Lock for a specific resource.
|
||||
*/
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
/**
|
||||
* Init the parameter metric and index map for given resource.
|
||||
* Package-private for test.
|
||||
*
|
||||
* @param resourceWrapper resource to init
|
||||
* @param rule relevant rule
|
||||
*/
|
||||
public static void initParamMetricsFor(ResourceWrapper resourceWrapper, /*@Valid*/ ParamFlowRule rule) {
|
||||
if (resourceWrapper == null || resourceWrapper.getName() == null) {
|
||||
return;
|
||||
}
|
||||
String resourceName = resourceWrapper.getName();
|
||||
ParameterMetric metric;
|
||||
// Assume that the resource is valid.
|
||||
if ((metric = metricsMap.get(resourceName)) == null) {
|
||||
synchronized (LOCK) {
|
||||
if ((metric = metricsMap.get(resourceName)) == null) {
|
||||
metric = new ParameterMetric();
|
||||
metricsMap.put(resourceWrapper.getName(), metric);
|
||||
RecordLog.info("[ParameterMetricStorage] Creating parameter metric for: " + resourceWrapper.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
metric.initialize(rule);
|
||||
}
|
||||
|
||||
public static ParameterMetric getParamMetric(ResourceWrapper resourceWrapper) {
|
||||
if (resourceWrapper == null || resourceWrapper.getName() == null) {
|
||||
return null;
|
||||
}
|
||||
return metricsMap.get(resourceWrapper.getName());
|
||||
}
|
||||
|
||||
public static ParameterMetric getParamMetricForResource(String resourceName) {
|
||||
if (resourceName == null) {
|
||||
return null;
|
||||
}
|
||||
return metricsMap.get(resourceName);
|
||||
}
|
||||
|
||||
public static void clearParamMetricForResource(String resourceName) {
|
||||
if (StringUtil.isBlank(resourceName)) {
|
||||
return;
|
||||
}
|
||||
metricsMap.remove(resourceName);
|
||||
RecordLog.info("[ParameterMetricStorage] Clearing parameter metric for: " + resourceName);
|
||||
}
|
||||
|
||||
static Map<String, ParameterMetric> getMetricsMap() {
|
||||
return metricsMap;
|
||||
}
|
||||
|
||||
private ParameterMetricStorage() {}
|
||||
}
|
||||
|
|
@ -20,8 +20,8 @@ import com.alibaba.csp.sentinel.node.DefaultNode;
|
|||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotEntryCallback;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowSlot;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParameterMetric;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParameterMetricStorage;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
|
|
@ -32,7 +32,7 @@ public class ParamFlowStatisticEntryCallback implements ProcessorSlotEntryCallba
|
|||
@Override
|
||||
public void onPass(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, Object... args) {
|
||||
// The "hot spot" parameter metric is present only if parameter flow rules for the resource exist.
|
||||
ParameterMetric parameterMetric = ParamFlowSlot.getParamMetric(resourceWrapper);
|
||||
ParameterMetric parameterMetric = ParameterMetricStorage.getParamMetric(resourceWrapper);
|
||||
|
||||
if (parameterMetric != null) {
|
||||
parameterMetric.addThreadCount(args);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ package com.alibaba.csp.sentinel.slots.statistic;
|
|||
import com.alibaba.csp.sentinel.context.Context;
|
||||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotExitCallback;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowSlot;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParameterMetric;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParameterMetricStorage;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
|
|
@ -30,7 +30,7 @@ public class ParamFlowStatisticExitCallback implements ProcessorSlotExitCallback
|
|||
@Override
|
||||
public void onExit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
|
||||
if (context.getCurEntry().getError() == null) {
|
||||
ParameterMetric parameterMetric = ParamFlowSlot.getParamMetric(resourceWrapper);
|
||||
ParameterMetric parameterMetric = ParameterMetricStorage.getParamMetric(resourceWrapper);
|
||||
|
||||
if (parameterMetric != null) {
|
||||
parameterMetric.decreaseThreadCount(args);
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ public class ParamFlowCheckerTest {
|
|||
rule.setParsedHotItems(map);
|
||||
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
|
||||
assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA));
|
||||
|
|
@ -127,7 +127,7 @@ public class ParamFlowCheckerTest {
|
|||
when(metric.getThreadCount(paramIdx, valueB)).thenReturn(globalThreshold - 1);
|
||||
when(metric.getThreadCount(paramIdx, valueC)).thenReturn(globalThreshold - 1);
|
||||
when(metric.getThreadCount(paramIdx, valueD)).thenReturn(globalThreshold + 1);
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
|
||||
assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA));
|
||||
assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueB));
|
||||
|
|
@ -158,7 +158,7 @@ public class ParamFlowCheckerTest {
|
|||
String v1 = "a", v2 = "B", v3 = "Cc";
|
||||
List<String> list = Arrays.asList(v1, v2, v3);
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
metric.getRuleTokenCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicInteger>(4000));
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ public class ParamFlowCheckerTest {
|
|||
String v1 = "a", v2 = "B", v3 = "Cc";
|
||||
Object arr = new String[] {v1, v2, v3};
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
|
||||
assertTrue(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, arr));
|
||||
|
|
@ -190,11 +190,11 @@ public class ParamFlowCheckerTest {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* Copyright 1999-2019 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
@ -41,7 +56,7 @@ public class ParamFlowDefaultCheckerTest extends AbstractTimeBasedTest {
|
|||
|
||||
String valueA = "valueA";
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
metric.getRuleTokenCounterMap().put(rule,
|
||||
new ConcurrentLinkedHashMapWrapper<Object, AtomicInteger>(4000));
|
||||
|
|
@ -81,7 +96,7 @@ public class ParamFlowDefaultCheckerTest extends AbstractTimeBasedTest {
|
|||
|
||||
String valueA = "valueA";
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
metric.getRuleTokenCounterMap().put(rule,
|
||||
new ConcurrentLinkedHashMapWrapper<Object, AtomicInteger>(4000));
|
||||
|
|
@ -151,7 +166,7 @@ public class ParamFlowDefaultCheckerTest extends AbstractTimeBasedTest {
|
|||
|
||||
String valueA = "helloWorld";
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
metric.getRuleTokenCounterMap().put(rule,
|
||||
new ConcurrentLinkedHashMapWrapper<Object, AtomicInteger>(4000));
|
||||
|
|
@ -204,7 +219,7 @@ public class ParamFlowDefaultCheckerTest extends AbstractTimeBasedTest {
|
|||
|
||||
final String valueA = "valueA";
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
metric.getRuleTokenCounterMap().put(rule,
|
||||
new ConcurrentLinkedHashMapWrapper<Object, AtomicInteger>(4000));
|
||||
|
|
@ -270,11 +285,11 @@ public class ParamFlowDefaultCheckerTest extends AbstractTimeBasedTest {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
|
||||
import org.junit.After;
|
||||
|
|
@ -40,33 +38,36 @@ public class ParamFlowRuleManagerTest {
|
|||
@Before
|
||||
public void setUp() {
|
||||
ParamFlowRuleManager.loadRules(null);
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ParamFlowRuleManager.loadRules(null);
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadHotParamRulesClearingUnusedMetrics() {
|
||||
public void testLoadParamRulesClearingUnusedMetrics() {
|
||||
final String resA = "resA";
|
||||
ParamFlowRule ruleA = new ParamFlowRule(resA)
|
||||
.setCount(1)
|
||||
.setParamIdx(0);
|
||||
ParamFlowRuleManager.loadRules(Collections.singletonList(ruleA));
|
||||
ParamFlowSlot.getMetricsMap().put(new StringResourceWrapper(resA, EntryType.IN), new ParameterMetric());
|
||||
assertNotNull(ParamFlowSlot.getHotParamMetricForName(resA));
|
||||
ParameterMetricStorage.getMetricsMap().put(resA, new ParameterMetric());
|
||||
assertNotNull(ParameterMetricStorage.getParamMetricForResource(resA));
|
||||
|
||||
final String resB = "resB";
|
||||
ParamFlowRule ruleB = new ParamFlowRule(resB)
|
||||
.setCount(2)
|
||||
.setParamIdx(1);
|
||||
ParamFlowRuleManager.loadRules(Collections.singletonList(ruleB));
|
||||
assertNull("The unused hot param metric should be cleared", ParamFlowSlot.getHotParamMetricForName(resA));
|
||||
assertNull("The unused hot param metric should be cleared",
|
||||
ParameterMetricStorage.getParamMetricForResource(resA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadHotParamRulesAndGet() {
|
||||
public void testLoadParamRulesAndGet() {
|
||||
final String resA = "abc";
|
||||
final String resB = "foo";
|
||||
final String resC = "baz";
|
||||
|
|
@ -107,4 +108,4 @@ public class ParamFlowRuleManagerTest {
|
|||
assertTrue(allRules.contains(ruleC));
|
||||
assertTrue(allRules.contains(ruleD));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class ParamFlowSlotTest {
|
|||
ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
paramFlowSlot.entry(null, resourceWrapper, null, 1, false, "abc");
|
||||
// The parameter metric instance will not be created.
|
||||
assertNull(ParamFlowSlot.getParamMetric(resourceWrapper));
|
||||
assertNull(ParameterMetricStorage.getParamMetric(resourceWrapper));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -106,7 +106,7 @@ public class ParamFlowSlotTest {
|
|||
map.put(argToGo, new AtomicLong(TimeUtil.currentTimeMillis()));
|
||||
|
||||
// Insert the mock metric to control pass or block.
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
|
||||
// The first entry will pass.
|
||||
paramFlowSlot.entry(null, resourceWrapper, null, 1, false, argToGo);
|
||||
|
|
@ -121,48 +121,16 @@ public class ParamFlowSlotTest {
|
|||
fail("The second entry should be blocked");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNullParamMetric() {
|
||||
assertNull(ParamFlowSlot.getParamMetric(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitParamMetrics() {
|
||||
|
||||
ParamFlowRule rule = new ParamFlowRule();
|
||||
rule.setParamIdx(1);
|
||||
int index = 1;
|
||||
String resourceName = "res-" + System.currentTimeMillis();
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
|
||||
assertNull(ParamFlowSlot.getParamMetric(resourceWrapper));
|
||||
|
||||
paramFlowSlot.initHotParamMetricsFor(resourceWrapper, rule);
|
||||
ParameterMetric metric = ParamFlowSlot.getParamMetric(resourceWrapper);
|
||||
assertNotNull(metric);
|
||||
assertNotNull(metric.getRuleTimeCounterMap().get(rule));
|
||||
assertNotNull(metric.getThreadCountMap().get(index));
|
||||
|
||||
// Duplicate init.
|
||||
paramFlowSlot.initHotParamMetricsFor(resourceWrapper, rule);
|
||||
assertSame(metric, ParamFlowSlot.getParamMetric(resourceWrapper));
|
||||
|
||||
ParamFlowRule rule2 = new ParamFlowRule();
|
||||
rule2.setParamIdx(1);
|
||||
assertSame(metric, ParamFlowSlot.getParamMetric(resourceWrapper));
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
public void setUp() {
|
||||
ParamFlowRuleManager.loadRules(null);
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
public void tearDown() {
|
||||
// Clean the metrics map.
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParamFlowRuleManager.loadRules(null);
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,20 @@
|
|||
/*
|
||||
* Copyright 1999-2019 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
|
@ -19,6 +32,8 @@ import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
|||
import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper;
|
||||
import com.alibaba.csp.sentinel.util.TimeUtil;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author jialiang.linjl
|
||||
*/
|
||||
|
|
@ -41,7 +56,7 @@ public class ParamFlowThrottleRateLimitingCheckerTest {
|
|||
|
||||
String valueA = "valueA";
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
|
||||
long currentTime = TimeUtil.currentTimeMillis();
|
||||
|
|
@ -85,7 +100,7 @@ public class ParamFlowThrottleRateLimitingCheckerTest {
|
|||
|
||||
final String valueA = "valueA";
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParamFlowSlot.getMetricsMap().put(resourceWrapper, metric);
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
|
||||
int threadCount = 40;
|
||||
|
|
@ -154,11 +169,11 @@ public class ParamFlowThrottleRateLimitingCheckerTest {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ParamFlowSlot.getMetricsMap().clear();
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 1999-2019 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class ParameterMetricStorageTest {
|
||||
|
||||
@Test
|
||||
public void testGetNullParamMetric() {
|
||||
assertNull(ParameterMetricStorage.getParamMetric(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitParamMetrics() {
|
||||
ParamFlowRule rule = new ParamFlowRule();
|
||||
rule.setParamIdx(1);
|
||||
int index = 1;
|
||||
String resourceName = "res-" + System.currentTimeMillis();
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
|
||||
assertNull(ParameterMetricStorage.getParamMetric(resourceWrapper));
|
||||
|
||||
ParameterMetricStorage.initParamMetricsFor(resourceWrapper, rule);
|
||||
ParameterMetric metric = ParameterMetricStorage.getParamMetric(resourceWrapper);
|
||||
assertNotNull(metric);
|
||||
assertNotNull(metric.getRuleTimeCounterMap().get(rule));
|
||||
assertNotNull(metric.getThreadCountMap().get(index));
|
||||
|
||||
// Duplicate init.
|
||||
ParameterMetricStorage.initParamMetricsFor(resourceWrapper, rule);
|
||||
assertSame(metric, ParameterMetricStorage.getParamMetric(resourceWrapper));
|
||||
|
||||
ParamFlowRule rule2 = new ParamFlowRule();
|
||||
rule2.setParamIdx(1);
|
||||
assertSame(metric, ParameterMetricStorage.getParamMetric(resourceWrapper));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue