Search in sources :

Example 1 with RequestRateLimiter

use of io.confluent.kafkarest.ratelimit.RequestRateLimiter in project kafka-rest by confluentinc.

the class ProduceRateLimitersTest method rateLimitedOnCountExceptionThrown.

@Test
@Inject
public void rateLimitedOnCountExceptionThrown() {
    Properties properties = new Properties();
    properties.put(PRODUCE_RATE_LIMIT_ENABLED, "true");
    properties.put(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS, Integer.toString(3600000));
    Provider<RequestRateLimiter> countLimitProvider = mock(Provider.class);
    Provider<RequestRateLimiter> bytesLimitProvider = mock(Provider.class);
    RequestRateLimiter rateLimiterForCount = mock(RequestRateLimiter.class);
    RequestRateLimiter rateLimiterForBytes = mock(RequestRateLimiter.class);
    expect(countLimitProvider.get()).andReturn(rateLimiterForCount);
    expect(bytesLimitProvider.get()).andReturn(rateLimiterForBytes);
    rateLimiterForCount.rateLimit(anyInt());
    rateLimiterForBytes.rateLimit(anyInt());
    rateLimiterForCount.rateLimit(anyInt());
    EasyMock.expectLastCall().andThrow(new RateLimitExceededException());
    replay(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
    ProduceRateLimiters produceRateLimiters = new ProduceRateLimiters(countLimitProvider, bytesLimitProvider, Boolean.parseBoolean(properties.getProperty(PRODUCE_RATE_LIMIT_ENABLED)), Duration.ofMillis(Integer.parseInt(properties.getProperty(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS))));
    produceRateLimiters.rateLimit("clusterId", 10L);
    RateLimitExceededException e = assertThrows(RateLimitExceededException.class, () -> produceRateLimiters.rateLimit("clusterId", 10L));
    assertEquals("The rate limit of requests per second has been exceeded.", e.getMessage());
    verify(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
}
Also used : RequestRateLimiter(io.confluent.kafkarest.ratelimit.RequestRateLimiter) RateLimitExceededException(io.confluent.kafkarest.ratelimit.RateLimitExceededException) ProduceRateLimiters(io.confluent.kafkarest.resources.v3.ProduceRateLimiters) Properties(java.util.Properties) Inject(javax.inject.Inject) Test(org.junit.jupiter.api.Test)

Example 2 with RequestRateLimiter

use of io.confluent.kafkarest.ratelimit.RequestRateLimiter in project kafka-rest by confluentinc.

the class ProduceRateLimitersTest method rateLimitingDisabledNoWaitTimeGiven.

@Test
@Inject
public void rateLimitingDisabledNoWaitTimeGiven() {
    Properties properties = new Properties();
    properties.put(PRODUCE_RATE_LIMIT_ENABLED, "false");
    properties.put(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS, Integer.toString(3600000));
    Provider<RequestRateLimiter> countLimitProvider = mock(Provider.class);
    Provider<RequestRateLimiter> bytesLimitProvider = mock(Provider.class);
    RequestRateLimiter rateLimiterForCount = mock(RequestRateLimiter.class);
    RequestRateLimiter rateLimiterForBytes = mock(RequestRateLimiter.class);
    replay(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
    ProduceRateLimiters produceRateLimiters = new ProduceRateLimiters(countLimitProvider, bytesLimitProvider, Boolean.parseBoolean(properties.getProperty(PRODUCE_RATE_LIMIT_ENABLED)), Duration.ofMillis(Integer.parseInt(properties.getProperty(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS))));
    produceRateLimiters.rateLimit("clusterId", 10L);
    verify(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
}
Also used : RequestRateLimiter(io.confluent.kafkarest.ratelimit.RequestRateLimiter) ProduceRateLimiters(io.confluent.kafkarest.resources.v3.ProduceRateLimiters) Properties(java.util.Properties) Inject(javax.inject.Inject) Test(org.junit.jupiter.api.Test)

Example 3 with RequestRateLimiter

use of io.confluent.kafkarest.ratelimit.RequestRateLimiter in project kafka-rest by confluentinc.

the class ProduceRateLimitersTest method cacheExpiresforeRateLimit.

@Test
public void cacheExpiresforeRateLimit() throws InterruptedException {
    Properties properties = new Properties();
    properties.put(PRODUCE_RATE_LIMIT_ENABLED, "true");
    properties.put(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS, Integer.toString(20));
    Provider<RequestRateLimiter> countLimitProvider = mock(Provider.class);
    Provider<RequestRateLimiter> bytesLimitProvider = mock(Provider.class);
    RequestRateLimiter rateLimiterForCount = mock(RequestRateLimiter.class);
    RequestRateLimiter rateLimiterForBytes = mock(RequestRateLimiter.class);
    expect(countLimitProvider.get()).andReturn(rateLimiterForCount);
    expect(bytesLimitProvider.get()).andReturn(rateLimiterForBytes);
    rateLimiterForCount.rateLimit(anyInt());
    rateLimiterForBytes.rateLimit(anyInt());
    // these are called after the delay that will reset the cache
    expect(countLimitProvider.get()).andReturn(rateLimiterForCount);
    expect(bytesLimitProvider.get()).andReturn(rateLimiterForBytes);
    rateLimiterForCount.rateLimit(anyInt());
    rateLimiterForBytes.rateLimit(anyInt());
    replay(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
    ProduceRateLimiters produceRateLimiters = new ProduceRateLimiters(countLimitProvider, bytesLimitProvider, Boolean.parseBoolean(properties.getProperty(PRODUCE_RATE_LIMIT_ENABLED)), Duration.ofMillis(Integer.parseInt(properties.getProperty(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS))));
    produceRateLimiters.rateLimit("clusterId", 10L);
    Thread.sleep(50);
    produceRateLimiters.rateLimit("clusterId", 10L);
    verify(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
}
Also used : RequestRateLimiter(io.confluent.kafkarest.ratelimit.RequestRateLimiter) ProduceRateLimiters(io.confluent.kafkarest.resources.v3.ProduceRateLimiters) Properties(java.util.Properties) Test(org.junit.jupiter.api.Test)

Example 4 with RequestRateLimiter

use of io.confluent.kafkarest.ratelimit.RequestRateLimiter in project kafka-rest by confluentinc.

the class ProduceActionTest method produceNoLimit.

@Test
public void produceNoLimit() throws Exception {
    // config
    final int TOTAL_NUMBER_OF_PRODUCE_CALLS = 2;
    Properties properties = new Properties();
    properties.put(PRODUCE_MAX_REQUESTS_PER_SECOND, "100");
    properties.put(PRODUCE_MAX_BYTES_PER_SECOND, // first record is 25 bytes long
    Integer.toString(30));
    properties.put(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS, "3600000");
    properties.put(PRODUCE_RATE_LIMIT_ENABLED, "falsse");
    // setup
    ChunkedOutputFactory chunkedOutputFactory = mock(ChunkedOutputFactory.class);
    ChunkedOutput<ResultOrError> mockedChunkedOutput = getChunkedOutput(chunkedOutputFactory, TOTAL_NUMBER_OF_PRODUCE_CALLS);
    Provider<RequestRateLimiter> countLimitProvider = mock(Provider.class);
    Provider<RequestRateLimiter> bytesLimitProvider = mock(Provider.class);
    RequestRateLimiter rateLimiterForCount = mock(RequestRateLimiter.class);
    RequestRateLimiter rateLimiterForBytes = mock(RequestRateLimiter.class);
    replay(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
    ProduceAction produceAction = getProduceAction(properties, chunkedOutputFactory, 2, countLimitProvider, bytesLimitProvider);
    MappingIterator<ProduceRequest> requests = getProduceRequestsMappingIterator(TOTAL_NUMBER_OF_PRODUCE_CALLS);
    // expected results
    ProduceResponse produceResponse = getProduceResponse(0);
    ResultOrError resultOrErrorOK1 = ResultOrError.result(produceResponse);
    expect(mockedChunkedOutput.isClosed()).andReturn(false);
    // successful first produce
    mockedChunkedOutput.write(resultOrErrorOK1);
    mockedChunkedOutput.close();
    ProduceResponse produceResponse2 = getProduceResponse(1);
    ResultOrError resultOrErrorOK2 = ResultOrError.result(produceResponse2);
    expect(mockedChunkedOutput.isClosed()).andReturn(false);
    // successful second produce
    mockedChunkedOutput.write(resultOrErrorOK2);
    mockedChunkedOutput.close();
    replay(mockedChunkedOutput, chunkedOutputFactory);
    // run test
    FakeAsyncResponse fakeAsyncResponse = new FakeAsyncResponse();
    produceAction.produce(fakeAsyncResponse, "clusterId", "topicName", requests);
    FakeAsyncResponse fakeAsyncResponse2 = new FakeAsyncResponse();
    produceAction.produce(fakeAsyncResponse2, "clusterId", "topicName", requests);
    // check results
    verify(requests, mockedChunkedOutput, countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
}
Also used : ChunkedOutputFactory(io.confluent.kafkarest.response.ChunkedOutputFactory) ResultOrError(io.confluent.kafkarest.response.StreamingResponse.ResultOrError) RequestRateLimiter(io.confluent.kafkarest.ratelimit.RequestRateLimiter) ProduceRequest(io.confluent.kafkarest.entities.v3.ProduceRequest) ProduceResponse(io.confluent.kafkarest.entities.v3.ProduceResponse) FakeAsyncResponse(io.confluent.kafkarest.response.FakeAsyncResponse) Properties(java.util.Properties) Test(org.junit.jupiter.api.Test)

Example 5 with RequestRateLimiter

use of io.confluent.kafkarest.ratelimit.RequestRateLimiter in project kafka-rest by confluentinc.

the class ProduceActionTest method produceWithCountLimit.

@Test
public void produceWithCountLimit() throws Exception {
    // config
    final int TOTAL_NUMBER_OF_PRODUCE_CALLS = 2;
    Properties properties = new Properties();
    properties.put(PRODUCE_MAX_REQUESTS_PER_SECOND, "100");
    properties.put(PRODUCE_MAX_BYTES_PER_SECOND, // first record is 25 bytes long
    Integer.toString(30));
    properties.put(PRODUCE_RATE_LIMIT_CACHE_EXPIRY_MS, "3600000");
    properties.put(PRODUCE_RATE_LIMIT_ENABLED, "true");
    // setup
    ChunkedOutputFactory chunkedOutputFactory = mock(ChunkedOutputFactory.class);
    ChunkedOutput<ResultOrError> mockedChunkedOutput = getChunkedOutput(chunkedOutputFactory, TOTAL_NUMBER_OF_PRODUCE_CALLS);
    Provider<RequestRateLimiter> countLimitProvider = mock(Provider.class);
    Provider<RequestRateLimiter> bytesLimitProvider = mock(Provider.class);
    RequestRateLimiter rateLimiterForCount = mock(RequestRateLimiter.class);
    RequestRateLimiter rateLimiterForBytes = mock(RequestRateLimiter.class);
    expect(countLimitProvider.get()).andReturn(rateLimiterForCount);
    expect(bytesLimitProvider.get()).andReturn(rateLimiterForBytes);
    rateLimiterForCount.rateLimit(anyInt());
    rateLimiterForBytes.rateLimit(anyInt());
    rateLimiterForCount.rateLimit(anyInt());
    EasyMock.expectLastCall().andThrow(new RateLimitExceededException());
    replay(countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
    ProduceAction produceAction = getProduceAction(properties, chunkedOutputFactory, 1, countLimitProvider, bytesLimitProvider);
    MappingIterator<ProduceRequest> requests = getProduceRequestsMappingIterator(TOTAL_NUMBER_OF_PRODUCE_CALLS);
    // expected results
    ProduceResponse produceResponse = getProduceResponse(0);
    ResultOrError resultOrErrorOK = ResultOrError.result(produceResponse);
    expect(mockedChunkedOutput.isClosed()).andReturn(false);
    // successful first produce
    mockedChunkedOutput.write(resultOrErrorOK);
    mockedChunkedOutput.close();
    ErrorResponse err = ErrorResponse.create(429, "Request rate limit exceeded: The rate limit of requests per second has been exceeded.");
    ResultOrError resultOrErrorFail = ResultOrError.error(err);
    expect(mockedChunkedOutput.isClosed()).andReturn(false);
    // failing second produce
    mockedChunkedOutput.write(resultOrErrorFail);
    // error close
    mockedChunkedOutput.close();
    replay(mockedChunkedOutput, chunkedOutputFactory);
    // run test
    FakeAsyncResponse fakeAsyncResponse = new FakeAsyncResponse();
    produceAction.produce(fakeAsyncResponse, "clusterId", "topicName", requests);
    FakeAsyncResponse fakeAsyncResponse2 = new FakeAsyncResponse();
    produceAction.produce(fakeAsyncResponse2, "clusterId", "topicName", requests);
    // check results
    verify(requests, mockedChunkedOutput, countLimitProvider, bytesLimitProvider, rateLimiterForCount, rateLimiterForBytes);
}
Also used : ChunkedOutputFactory(io.confluent.kafkarest.response.ChunkedOutputFactory) ProduceRequest(io.confluent.kafkarest.entities.v3.ProduceRequest) ProduceResponse(io.confluent.kafkarest.entities.v3.ProduceResponse) FakeAsyncResponse(io.confluent.kafkarest.response.FakeAsyncResponse) RateLimitExceededException(io.confluent.kafkarest.ratelimit.RateLimitExceededException) Properties(java.util.Properties) ErrorResponse(io.confluent.kafkarest.exceptions.v3.ErrorResponse) ResultOrError(io.confluent.kafkarest.response.StreamingResponse.ResultOrError) RequestRateLimiter(io.confluent.kafkarest.ratelimit.RequestRateLimiter) Test(org.junit.jupiter.api.Test)

Aggregations

RequestRateLimiter (io.confluent.kafkarest.ratelimit.RequestRateLimiter)12 Properties (java.util.Properties)11 Test (org.junit.jupiter.api.Test)11 ProduceRequest (io.confluent.kafkarest.entities.v3.ProduceRequest)6 ChunkedOutputFactory (io.confluent.kafkarest.response.ChunkedOutputFactory)6 FakeAsyncResponse (io.confluent.kafkarest.response.FakeAsyncResponse)6 ProduceRateLimiters (io.confluent.kafkarest.resources.v3.ProduceRateLimiters)5 ResultOrError (io.confluent.kafkarest.response.StreamingResponse.ResultOrError)5 ProduceResponse (io.confluent.kafkarest.entities.v3.ProduceResponse)4 RateLimitExceededException (io.confluent.kafkarest.ratelimit.RateLimitExceededException)4 Inject (javax.inject.Inject)4 ErrorResponse (io.confluent.kafkarest.exceptions.v3.ErrorResponse)3 RestConstraintViolationException (io.confluent.rest.exceptions.RestConstraintViolationException)1