Search in sources :

Example 61 with FlowRule

use of com.alibaba.csp.sentinel.slots.block.flow.FlowRule in project Sentinel by alibaba.

the class SentinelEnvoyRlsServiceImplTest method testShouldRateLimitPass.

@Test
public void testShouldRateLimitPass() {
    SentinelEnvoyRlsServiceImpl rlsService = mock(SentinelEnvoyRlsServiceImpl.class);
    StreamObserver<RateLimitResponse> streamObserver = mock(StreamObserver.class);
    String domain = "testShouldRateLimitPass";
    int acquireCount = 1;
    RateLimitDescriptor descriptor1 = RateLimitDescriptor.newBuilder().addEntries(RateLimitDescriptor.Entry.newBuilder().setKey("rk1").setValue("rv1").build()).build();
    RateLimitDescriptor descriptor2 = RateLimitDescriptor.newBuilder().addEntries(RateLimitDescriptor.Entry.newBuilder().setKey("rk2").setValue("rv2").build()).addEntries(RateLimitDescriptor.Entry.newBuilder().setKey("rk3").setValue("rv3").build()).build();
    ArgumentCaptor<RateLimitResponse> responseCapture = ArgumentCaptor.forClass(RateLimitResponse.class);
    doNothing().when(streamObserver).onNext(responseCapture.capture());
    doCallRealMethod().when(rlsService).shouldRateLimit(any(), any());
    when(rlsService.checkToken(eq(domain), same(descriptor1), eq(acquireCount))).thenReturn(Tuple2.of(new FlowRule(), new TokenResult(TokenResultStatus.OK)));
    when(rlsService.checkToken(eq(domain), same(descriptor2), eq(acquireCount))).thenReturn(Tuple2.of(new FlowRule(), new TokenResult(TokenResultStatus.OK)));
    RateLimitRequest rateLimitRequest = RateLimitRequest.newBuilder().addDescriptors(descriptor1).addDescriptors(descriptor2).setDomain(domain).setHitsAddend(acquireCount).build();
    rlsService.shouldRateLimit(rateLimitRequest, streamObserver);
    RateLimitResponse response = responseCapture.getValue();
    assertEquals(RateLimitResponse.Code.OK, response.getOverallCode());
    response.getStatusesList().forEach(e -> assertEquals(RateLimitResponse.Code.OK, e.getCode()));
}
Also used : RateLimitDescriptor(io.envoyproxy.envoy.extensions.common.ratelimit.v3.RateLimitDescriptor) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) RateLimitRequest(io.envoyproxy.envoy.service.ratelimit.v3.RateLimitRequest) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule) RateLimitResponse(io.envoyproxy.envoy.service.ratelimit.v3.RateLimitResponse) Test(org.junit.Test)

Example 62 with FlowRule

use of com.alibaba.csp.sentinel.slots.block.flow.FlowRule in project Sentinel by alibaba.

the class SentinelEnvoyRlsServiceImplTest method testShouldRatePartialBlock.

@Test
public void testShouldRatePartialBlock() {
    SentinelEnvoyRlsServiceImpl rlsService = mock(SentinelEnvoyRlsServiceImpl.class);
    StreamObserver<RateLimitResponse> streamObserver = mock(StreamObserver.class);
    String domain = "testShouldRatePartialBlock";
    int acquireCount = 1;
    RateLimitDescriptor descriptor1 = RateLimitDescriptor.newBuilder().addEntries(RateLimitDescriptor.Entry.newBuilder().setKey("rk1").setValue("rv1").build()).build();
    RateLimitDescriptor descriptor2 = RateLimitDescriptor.newBuilder().addEntries(RateLimitDescriptor.Entry.newBuilder().setKey("rk2").setValue("rv2").build()).addEntries(RateLimitDescriptor.Entry.newBuilder().setKey("rk3").setValue("rv3").build()).build();
    ArgumentCaptor<RateLimitResponse> responseCapture = ArgumentCaptor.forClass(RateLimitResponse.class);
    doNothing().when(streamObserver).onNext(responseCapture.capture());
    doCallRealMethod().when(rlsService).shouldRateLimit(any(), any());
    when(rlsService.checkToken(eq(domain), same(descriptor1), eq(acquireCount))).thenReturn(Tuple2.of(new FlowRule(), new TokenResult(TokenResultStatus.BLOCKED)));
    when(rlsService.checkToken(eq(domain), same(descriptor2), eq(acquireCount))).thenReturn(Tuple2.of(new FlowRule(), new TokenResult(TokenResultStatus.OK)));
    RateLimitRequest rateLimitRequest = RateLimitRequest.newBuilder().addDescriptors(descriptor1).addDescriptors(descriptor2).setDomain(domain).setHitsAddend(acquireCount).build();
    rlsService.shouldRateLimit(rateLimitRequest, streamObserver);
    RateLimitResponse response = responseCapture.getValue();
    assertEquals(RateLimitResponse.Code.OVER_LIMIT, response.getOverallCode());
    assertEquals(2, response.getStatusesCount());
    assertTrue(response.getStatusesList().stream().anyMatch(e -> e.getCode().equals(RateLimitResponse.Code.OVER_LIMIT)));
    assertFalse(response.getStatusesList().stream().allMatch(e -> e.getCode().equals(RateLimitResponse.Code.OVER_LIMIT)));
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) TokenResultStatus(com.alibaba.csp.sentinel.cluster.TokenResultStatus) RateLimitDescriptor(io.envoyproxy.envoy.extensions.common.ratelimit.v3.RateLimitDescriptor) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Tuple2(com.alibaba.csp.sentinel.util.function.Tuple2) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Mockito(org.mockito.Mockito) StreamObserver(io.grpc.stub.StreamObserver) ArgumentCaptor(org.mockito.ArgumentCaptor) RateLimitRequest(io.envoyproxy.envoy.service.ratelimit.v3.RateLimitRequest) RateLimitResponse(io.envoyproxy.envoy.service.ratelimit.v3.RateLimitResponse) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) Assert(org.junit.Assert) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule) ArgumentMatchers.same(org.mockito.ArgumentMatchers.same) RateLimitDescriptor(io.envoyproxy.envoy.extensions.common.ratelimit.v3.RateLimitDescriptor) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) RateLimitRequest(io.envoyproxy.envoy.service.ratelimit.v3.RateLimitRequest) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule) RateLimitResponse(io.envoyproxy.envoy.service.ratelimit.v3.RateLimitResponse) Test(org.junit.Test)

Example 63 with FlowRule

use of com.alibaba.csp.sentinel.slots.block.flow.FlowRule in project Sentinel by alibaba.

the class SentinelEnvoyRlsServiceImpl method checkToken.

protected Tuple2<FlowRule, TokenResult> checkToken(String domain, RateLimitDescriptor descriptor, int acquireCount) {
    long ruleId = EnvoySentinelRuleConverter.generateFlowId(generateKey(domain, descriptor));
    FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(ruleId);
    if (rule == null) {
        // Pass if the target rule is absent.
        return Tuple2.of(null, new TokenResult(TokenResultStatus.NO_RULE_EXISTS));
    }
    // If the rule is present, it should be valid.
    return Tuple2.of(rule, SimpleClusterFlowChecker.acquireClusterToken(rule, acquireCount));
}
Also used : TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule)

Example 64 with FlowRule

use of com.alibaba.csp.sentinel.slots.block.flow.FlowRule in project Sentinel by alibaba.

the class SentinelEnvoyRlsServiceImpl method shouldRateLimit.

@Override
public void shouldRateLimit(RateLimitRequest request, StreamObserver<RateLimitResponse> responseObserver) {
    int acquireCount = request.getHitsAddend();
    if (acquireCount < 0) {
        responseObserver.onError(new IllegalArgumentException("acquireCount should be positive, but actual: " + acquireCount));
        return;
    }
    if (acquireCount == 0) {
        // Not present, use the default "1" by default.
        acquireCount = 1;
    }
    String domain = request.getDomain();
    boolean blocked = false;
    List<DescriptorStatus> statusList = new ArrayList<>(request.getDescriptorsCount());
    for (RateLimitDescriptor descriptor : request.getDescriptorsList()) {
        Tuple2<FlowRule, TokenResult> t = checkToken(domain, descriptor, acquireCount);
        TokenResult r = t.r2;
        printAccessLogIfNecessary(domain, descriptor, r);
        if (r.getStatus() == TokenResultStatus.NO_RULE_EXISTS) {
            // If the rule of the descriptor is absent, the request will pass directly.
            r.setStatus(TokenResultStatus.OK);
        }
        if (!blocked && r.getStatus() != TokenResultStatus.OK) {
            blocked = true;
        }
        Code statusCode = r.getStatus() == TokenResultStatus.OK ? Code.OK : Code.OVER_LIMIT;
        DescriptorStatus.Builder descriptorStatusBuilder = DescriptorStatus.newBuilder().setCode(statusCode);
        if (t.r1 != null) {
            descriptorStatusBuilder.setCurrentLimit(RateLimit.newBuilder().setUnit(Unit.SECOND).setRequestsPerUnit((int) t.r1.getCount()).build()).setLimitRemaining(r.getRemaining());
        }
        statusList.add(descriptorStatusBuilder.build());
    }
    Code overallStatus = blocked ? Code.OVER_LIMIT : Code.OK;
    RateLimitResponse response = RateLimitResponse.newBuilder().setOverallCode(overallStatus).addAllStatuses(statusList).build();
    responseObserver.onNext(response);
    responseObserver.onCompleted();
}
Also used : DescriptorStatus(io.envoyproxy.envoy.service.ratelimit.v2.RateLimitResponse.DescriptorStatus) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) ArrayList(java.util.ArrayList) RateLimitResponse(io.envoyproxy.envoy.service.ratelimit.v2.RateLimitResponse) Code(io.envoyproxy.envoy.service.ratelimit.v2.RateLimitResponse.Code) RateLimitDescriptor(io.envoyproxy.envoy.api.v2.ratelimit.RateLimitDescriptor) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule)

Example 65 with FlowRule

use of com.alibaba.csp.sentinel.slots.block.flow.FlowRule in project Sentinel by alibaba.

the class ClusterFlowCheckerTest method testAcquireClusterTokenOccupyPass.

// @Test
public void testAcquireClusterTokenOccupyPass() {
    long flowId = 98765L;
    final int threshold = 5;
    FlowRule clusterRule = new FlowRule("abc").setCount(threshold).setClusterMode(true).setClusterConfig(new ClusterFlowConfig().setFlowId(flowId).setThresholdType(ClusterRuleConstant.FLOW_THRESHOLD_GLOBAL));
    int sampleCount = 5;
    int intervalInMs = 1000;
    int bucketLength = intervalInMs / sampleCount;
    ClusterMetric metric = new ClusterMetric(sampleCount, intervalInMs);
    ClusterMetricStatistics.putMetric(flowId, metric);
    System.out.println(System.currentTimeMillis());
    assertResultPass(tryAcquire(clusterRule, false));
    assertResultPass(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultPass(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultPass(tryAcquire(clusterRule, true));
    assertResultPass(tryAcquire(clusterRule, false));
    assertResultBlock(tryAcquire(clusterRule, true));
    sleep(bucketLength);
    assertResultBlock(tryAcquire(clusterRule, false));
    assertResultBlock(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultBlock(tryAcquire(clusterRule, false));
    assertResultWait(tryAcquire(clusterRule, true), bucketLength);
    assertResultBlock(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultPass(tryAcquire(clusterRule, false));
    ClusterMetricStatistics.removeMetric(flowId);
}
Also used : ClusterMetric(com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule) ClusterFlowConfig(com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig)

Aggregations

FlowRule (com.alibaba.csp.sentinel.slots.block.flow.FlowRule)113 ArrayList (java.util.ArrayList)31 Test (org.junit.Test)31 ClusterNode (com.alibaba.csp.sentinel.node.ClusterNode)22 List (java.util.List)17 TokenResult (com.alibaba.csp.sentinel.cluster.TokenResult)11 DegradeRule (com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule)9 BlockException (com.alibaba.csp.sentinel.slots.block.BlockException)6 Test (org.junit.jupiter.api.Test)6 ClusterFlowConfig (com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig)5 TypeReference (com.alibaba.fastjson.TypeReference)5 QuarkusUnitTest (io.quarkus.test.QuarkusUnitTest)5 Before (org.junit.Before)5 ParamFlowRule (com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule)4 ClusterMetric (com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric)3 FlowRuleManager (com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager)3 AbstractTimeBasedTest (com.alibaba.csp.sentinel.test.AbstractTimeBasedTest)3 RateLimitDescriptor (io.envoyproxy.envoy.extensions.common.ratelimit.v3.RateLimitDescriptor)3 RateLimitResponse (io.envoyproxy.envoy.service.ratelimit.v3.RateLimitResponse)3 IOException (java.io.IOException)3