Add support for extracting param from complex object (#1491)
* This could enable specified parameter flow control for customized objects.
This commit is contained in:
parent
2e64d33085
commit
0d7da77d03
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
/**
|
||||
* ParamFlowArgument
|
||||
*/
|
||||
public interface ParamFlowArgument {
|
||||
|
||||
/**
|
||||
* @return the object as a key of param flow limit
|
||||
*/
|
||||
Object paramFlowKey();
|
||||
}
|
||||
|
|
@ -56,8 +56,14 @@ public final class ParamFlowChecker {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Get parameter value. If value is null, then pass.
|
||||
// Get parameter value.
|
||||
Object value = args[paramIdx];
|
||||
|
||||
// Assign value with the result of paramFlowKey method
|
||||
if (value instanceof ParamFlowArgument) {
|
||||
value = ((ParamFlowArgument) value).paramFlowKey();
|
||||
}
|
||||
// If value is null, then pass
|
||||
if (value == null) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,29 +15,27 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
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 org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Test cases for {@link ParamFlowChecker}.
|
||||
|
|
@ -188,6 +186,41 @@ public class ParamFlowCheckerTest {
|
|||
assertFalse(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, arr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPassLocalCheckForComplexParam() throws InterruptedException {
|
||||
class User implements ParamFlowArgument {
|
||||
Integer id;
|
||||
String name;
|
||||
String address;
|
||||
|
||||
public User(Integer id, String name, String address) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object paramFlowKey() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
final String resourceName = "testPassLocalCheckForComplexParam";
|
||||
final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
int paramIdx = 0;
|
||||
double globalThreshold = 1;
|
||||
|
||||
ParamFlowRule rule = new ParamFlowRule(resourceName).setParamIdx(paramIdx).setCount(globalThreshold);
|
||||
|
||||
Object[] args = new Object[]{new User(1, "Bob", "Hangzhou"), 10, "Demo"};
|
||||
ParameterMetric metric = new ParameterMetric();
|
||||
ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric);
|
||||
metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
metric.getRuleTokenCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(4000));
|
||||
|
||||
assertTrue(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, args));
|
||||
assertFalse(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, args));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ParameterMetricStorage.getMetricsMap().clear();
|
||||
|
|
|
|||
Loading…
Reference in New Issue