Search in sources :

Example 1 with QuotaException

use of com.github.ambry.quota.QuotaException in project ambry by linkedin.

the class AmbrySecurityService method processRequestCharges.

@Override
public void processRequestCharges(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo) {
    Map<String, Double> requestCost = ambryCostModelPolicy.calculateRequestCost(restRequest, responseChannel, blobInfo);
    setRequestCostHeader(requestCost, responseChannel);
    if (QuotaUtils.isRequestResourceQuotaManaged(restRequest) && quotaManager != null) {
        ThrottlingRecommendation throttlingRecommendation = null;
        try {
            throttlingRecommendation = quotaManager.recommend(restRequest);
        } catch (QuotaException quotaException) {
            LOGGER.warn("Exception {} in while processing request charges.", quotaException);
        }
        if (throttlingRecommendation != null) {
            RestUtils.buildUserQuotaHeadersMap(throttlingRecommendation).entrySet().stream().forEach(headerEntry -> responseChannel.setHeader(headerEntry.getKey(), headerEntry.getValue()));
        }
    }
}
Also used : ThrottlingRecommendation(com.github.ambry.quota.ThrottlingRecommendation) QuotaException(com.github.ambry.quota.QuotaException)

Example 2 with QuotaException

use of com.github.ambry.quota.QuotaException in project ambry by linkedin.

the class AmbryCUQuotaEnforcerTest method testCharge.

@Test
public void testCharge() throws Exception {
    Container container = ACCOUNT.getAllContainers().iterator().next();
    Map<QuotaName, Double> readRequestCostMap = Collections.singletonMap(QuotaName.READ_CAPACITY_UNIT, 9.0);
    Map<QuotaName, Double> writeRequestCostMap = Collections.singletonMap(QuotaName.WRITE_CAPACITY_UNIT, 9.0);
    Map<String, CapacityUnit> usageMap = QUOTA_SOURCE.getAllQuotaUsage();
    // 1. Test that usage is updated and recommendation is serve when usage is within limit.
    RestRequest restRequest = QuotaTestUtils.createRestRequest(ACCOUNT, container, RestMethod.GET);
    AMBRY_QUOTA_ENFORCER.charge(restRequest, readRequestCostMap);
    QuotaRecommendation quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(restRequest);
    assertEquals(quotaRecommendation.getQuotaName(), QuotaName.READ_CAPACITY_UNIT);
    assertEquals(quotaRecommendation.getQuotaUsagePercentage(), 90, 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.ALLOW);
    // make sure that correct quota is charged.
    assertEquals(usageMap.get(String.valueOf(ACCOUNT.getId())).getWcu(), 0);
    restRequest = QuotaTestUtils.createRestRequest(ACCOUNT, container, RestMethod.POST);
    AMBRY_QUOTA_ENFORCER.charge(restRequest, writeRequestCostMap);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(restRequest);
    assertEquals(quotaRecommendation.getQuotaName(), QuotaName.WRITE_CAPACITY_UNIT);
    assertEquals(quotaRecommendation.getQuotaUsagePercentage(), 90, 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.ALLOW);
    // make sure that correct quota is charged.
    assertEquals(usageMap.get(String.valueOf(ACCOUNT.getId())).getRcu(), 9);
    // 2. Test that retryable quota exception is thrown when quota not found.
    Account newAccount = ACCOUNT_SERVICE.generateRandomAccount(QuotaResourceType.ACCOUNT);
    restRequest = QuotaTestUtils.createRestRequest(newAccount, newAccount.getAllContainers().iterator().next(), RestMethod.GET);
    try {
        AMBRY_QUOTA_ENFORCER.charge(restRequest, readRequestCostMap);
        AMBRY_QUOTA_ENFORCER.recommend(restRequest);
        fail("if quota is not found we should see exception");
    } catch (QuotaException quotaException) {
        Assert.assertTrue(quotaException.isRetryable());
    }
    // 3. Test that retryable quota exception is thrown in case of any error.
    restRequest = QuotaTestUtils.createRestRequest(ACCOUNT, container, RestMethod.GET);
    QUOTA_SOURCE.throwException = true;
    try {
        AMBRY_QUOTA_ENFORCER.charge(restRequest, readRequestCostMap);
        fail("QuotaException should be thrown in case of any error.");
    } catch (QuotaException quotaException) {
        Assert.assertTrue(quotaException.isRetryable());
    }
    QUOTA_SOURCE.throwException = false;
    // 4. Test that usage is updated and recommendation is deny when usage >= quota.
    AMBRY_QUOTA_ENFORCER.charge(restRequest, readRequestCostMap);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(restRequest);
    assertEquals(QuotaName.READ_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(180, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.DELAY);
    // make sure that correct quota is charged.
    assertEquals(9, usageMap.get(String.valueOf(ACCOUNT.getId())).getWcu());
    assertEquals(18, // make sure that correct quota is charged.
    usageMap.get(String.valueOf(ACCOUNT.getId())).getRcu());
    restRequest = QuotaTestUtils.createRestRequest(ACCOUNT, container, RestMethod.POST);
    AMBRY_QUOTA_ENFORCER.charge(restRequest, writeRequestCostMap);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(restRequest);
    assertEquals(QuotaName.WRITE_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(180, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.DELAY);
    assertEquals(18, // make sure that correct quota is charged.
    usageMap.get(String.valueOf(ACCOUNT.getId())).getWcu());
    assertEquals(18, // make sure that correct quota is charged.
    usageMap.get(String.valueOf(ACCOUNT.getId())).getRcu());
    restRequest = QuotaTestUtils.createRestRequest(ACCOUNT, container, RestMethod.DELETE);
    AMBRY_QUOTA_ENFORCER.charge(restRequest, writeRequestCostMap);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(restRequest);
    assertEquals(QuotaName.WRITE_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(270, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.DELAY);
    assertEquals(27, // make sure that correct quota is charged.
    usageMap.get(String.valueOf(ACCOUNT.getId())).getWcu());
    assertEquals(18, // make sure that correct quota is charged.
    usageMap.get(String.valueOf(ACCOUNT.getId())).getRcu());
    restRequest = QuotaTestUtils.createRestRequest(ACCOUNT, container, RestMethod.PUT);
    AMBRY_QUOTA_ENFORCER.charge(restRequest, writeRequestCostMap);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(restRequest);
    assertEquals(QuotaName.WRITE_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(360, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.DELAY);
    assertEquals(36, // make sure that correct quota is charged.
    usageMap.get(String.valueOf(ACCOUNT.getId())).getWcu());
    assertEquals(18, // make sure that correct quota is charged.
    usageMap.get(String.valueOf(ACCOUNT.getId())).getRcu());
}
Also used : QuotaName(com.github.ambry.quota.QuotaName) Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container) RestRequest(com.github.ambry.rest.RestRequest) QuotaException(com.github.ambry.quota.QuotaException) QuotaRecommendation(com.github.ambry.quota.QuotaRecommendation) Test(org.junit.Test)

Example 3 with QuotaException

use of com.github.ambry.quota.QuotaException in project ambry by linkedin.

the class MockReadableStreamChannel method testBadCallback.

/**
 * Test that a bad user defined callback will not crash the router.
 * @throws Exception
 */
@Test
public void testBadCallback() throws Exception {
    RequestAndResult req = new RequestAndResult(chunkSize * 5 + random.nextInt(chunkSize - 1) + 1);
    router = getNonBlockingRouter();
    final CountDownLatch callbackCalled = new CountDownLatch(1);
    requestAndResultsList.clear();
    for (int i = 0; i < 4; i++) {
        requestAndResultsList.add(new RequestAndResult(chunkSize + random.nextInt(5) * random.nextInt(chunkSize)));
    }
    instantiateNewRouterForPuts = false;
    ReadableStreamChannel putChannel = new ByteBufferReadableStreamChannel(ByteBuffer.wrap(req.putContent));
    Future future = router.putBlob(req.putBlobProperties, req.putUserMetadata, putChannel, req.options, (result, exception) -> {
        callbackCalled.countDown();
        throw new RuntimeException("Throwing an exception in the user callback");
    }, new QuotaChargeCallback() {

        @Override
        public void charge(long chunkSize) {
        }

        @Override
        public void charge() {
        }

        @Override
        public boolean check() {
            return false;
        }

        @Override
        public boolean quotaExceedAllowed() {
            return false;
        }

        @Override
        public QuotaResource getQuotaResource() throws QuotaException {
            return null;
        }

        @Override
        public QuotaMethod getQuotaMethod() {
            return null;
        }
    });
    submitPutsAndAssertSuccess(false);
    // future.get() for operation with bad callback should still succeed
    future.get();
    Assert.assertTrue("Callback not called.", callbackCalled.await(MAX_WAIT_MS, TimeUnit.MILLISECONDS));
    assertEquals("All operations should be finished.", 0, router.getOperationsCount());
    Assert.assertTrue("Router should not be closed", router.isOpen());
    // Test that PutManager is still operational
    requestAndResultsList.clear();
    requestAndResultsList.add(new RequestAndResult(chunkSize + random.nextInt(5) * random.nextInt(chunkSize)));
    instantiateNewRouterForPuts = false;
    submitPutsAndAssertSuccess(true);
}
Also used : ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) CountDownLatch(java.util.concurrent.CountDownLatch) QuotaResource(com.github.ambry.quota.QuotaResource) QuotaMethod(com.github.ambry.quota.QuotaMethod) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) Future(java.util.concurrent.Future) QuotaChargeCallback(com.github.ambry.quota.QuotaChargeCallback) QuotaException(com.github.ambry.quota.QuotaException) Test(org.junit.Test)

Example 4 with QuotaException

use of com.github.ambry.quota.QuotaException in project ambry by linkedin.

the class NonBlockingRouterQuotaCallbackTest method testRouterWithQuotaCallback.

/**
 * Test Router with single scaling unit for correct accounting in {@link QuotaChargeCallback}.
 */
@Test
public void testRouterWithQuotaCallback() throws Exception {
    try {
        setRouter();
        assertExpectedThreadCounts(2, 1);
        AtomicLong listenerCalledCount = new AtomicLong(0);
        int expectedChargeCallbackCount = 0;
        // create a quota charge listener that increments an atomic counter everytime its called.
        // Also tests that in case quota if charged in tracking mode with throttleInProgress config set to false
        // then the requests go through even in case of exception.
        QuotaChargeCallback quotaChargeCallback = new QuotaChargeCallback() {

            @Override
            public void charge(long chunkSize) throws QuotaException {
                listenerCalledCount.addAndGet(chunkSize);
                throw new QuotaException("exception during check and charge", new RouterException("Quota exceeded.", RouterErrorCode.TooManyRequests), false);
            }

            @Override
            public void charge() throws QuotaException {
                charge(quotaAccountingSize);
            }

            @Override
            public boolean check() {
                return false;
            }

            @Override
            public boolean quotaExceedAllowed() {
                return false;
            }

            @Override
            public QuotaResource getQuotaResource() {
                return null;
            }

            @Override
            public QuotaMethod getQuotaMethod() {
                return null;
            }
        };
        // test for a composite blob.
        int blobSize = 3000;
        setOperationParams(blobSize, TTL_SECS);
        String compositeBlobId = router.putBlob(putBlobProperties, putUserMetadata, putChannel, PutBlobOptions.DEFAULT, null, quotaChargeCallback).get();
        expectedChargeCallbackCount += blobSize;
        assertEquals(expectedChargeCallbackCount, listenerCalledCount.get());
        RetainingAsyncWritableChannel retainingAsyncWritableChannel = new RetainingAsyncWritableChannel();
        router.getBlob(compositeBlobId, new GetBlobOptionsBuilder().build(), null, quotaChargeCallback).get().getBlobDataChannel().readInto(retainingAsyncWritableChannel, null).get();
        expectedChargeCallbackCount += blobSize;
        // read out all the chunks to make sure all the chunks are consumed and accounted for.
        retainingAsyncWritableChannel.consumeContentAsInputStream().close();
        assertEquals(expectedChargeCallbackCount, listenerCalledCount.get());
        // test for regular blobs.
        setOperationParams();
        List<String> blobIds = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            setOperationParams();
            String blobId = router.putBlob(putBlobProperties, putUserMetadata, putChannel, PutBlobOptions.DEFAULT, null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += PUT_CONTENT_SIZE, listenerCalledCount.get());
            logger.info("Put blob {}", blobId);
            blobIds.add(blobId);
        }
        setOperationParams();
        for (String blobId : blobIds) {
            router.getBlob(blobId, new GetBlobOptionsBuilder().build(), null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += PUT_CONTENT_SIZE, listenerCalledCount.get());
            router.updateBlobTtl(blobId, null, Utils.Infinite_Time, null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += quotaAccountingSize, listenerCalledCount.get());
            router.getBlob(blobId, new GetBlobOptionsBuilder().build(), null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += PUT_CONTENT_SIZE, listenerCalledCount.get());
            router.getBlob(blobId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.BlobInfo).build(), null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += quotaAccountingSize, listenerCalledCount.get());
            router.deleteBlob(blobId, null, null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += quotaAccountingSize, listenerCalledCount.get());
            try {
                router.getBlob(blobId, new GetBlobOptionsBuilder().build(), null, quotaChargeCallback).get();
                fail("Get blob should fail");
            } catch (ExecutionException e) {
                RouterException r = (RouterException) e.getCause();
                Assert.assertEquals("BlobDeleted error is expected", RouterErrorCode.BlobDeleted, r.getErrorCode());
                assertEquals(expectedChargeCallbackCount, listenerCalledCount.get());
            }
            router.getBlob(blobId, new GetBlobOptionsBuilder().getOption(GetOption.Include_Deleted_Blobs).build(), null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += PUT_CONTENT_SIZE, listenerCalledCount.get());
            router.getBlob(blobId, new GetBlobOptionsBuilder().getOption(GetOption.Include_All).build(), null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += PUT_CONTENT_SIZE, listenerCalledCount.get());
        }
        // test for stitched blobs.
        blobIds = new ArrayList<>();
        int stitchedBlobCount = 2;
        for (int i = 0; i < stitchedBlobCount; i++) {
            setOperationParams();
            String blobId = router.putBlob(putBlobProperties, putUserMetadata, putChannel, PutBlobOptions.DEFAULT, null, quotaChargeCallback).get();
            assertEquals(expectedChargeCallbackCount += PUT_CONTENT_SIZE, listenerCalledCount.get());
            logger.info("Put blob {}", blobId);
            blobIds.add(blobId);
        }
        String stitchedBlobId = router.stitchBlob(putBlobProperties, putUserMetadata, blobIds.stream().map(blobId -> new ChunkInfo(blobId, PUT_CONTENT_SIZE, Utils.Infinite_Time)).collect(Collectors.toList()), null, quotaChargeCallback).get();
        assertEquals(expectedChargeCallbackCount, listenerCalledCount.get());
        retainingAsyncWritableChannel = new RetainingAsyncWritableChannel();
        router.getBlob(stitchedBlobId, new GetBlobOptionsBuilder().build(), null, quotaChargeCallback).get().getBlobDataChannel().readInto(retainingAsyncWritableChannel, null).get();
        // read out all the chunks to make sure all the chunks are consumed and accounted for.
        retainingAsyncWritableChannel.consumeContentAsInputStream().close();
        assertEquals(expectedChargeCallbackCount += (PUT_CONTENT_SIZE * stitchedBlobCount), listenerCalledCount.get());
        router.updateBlobTtl(stitchedBlobId, null, Utils.Infinite_Time, null, quotaChargeCallback).get();
        assertEquals(expectedChargeCallbackCount += quotaAccountingSize, listenerCalledCount.get());
        router.deleteBlob(stitchedBlobId, null, null, quotaChargeCallback).get();
        assertEquals(expectedChargeCallbackCount + quotaAccountingSize, listenerCalledCount.get());
    } finally {
        router.close();
        assertExpectedThreadCounts(0, 0);
        // submission after closing should return a future that is already done.
        assertClosed();
    }
}
Also used : GetOption(com.github.ambry.protocol.GetOption) Arrays(java.util.Arrays) RunWith(org.junit.runner.RunWith) LoggerFactory(org.slf4j.LoggerFactory) AccountService(com.github.ambry.account.AccountService) QuotaManager(com.github.ambry.quota.QuotaManager) ArrayList(java.util.ArrayList) QuotaConfig(com.github.ambry.config.QuotaConfig) QuotaMode(com.github.ambry.quota.QuotaMode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) QuotaResource(com.github.ambry.quota.QuotaResource) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) QuotaAction(com.github.ambry.quota.QuotaAction) RetainingAsyncWritableChannel(com.github.ambry.commons.RetainingAsyncWritableChannel) QuotaMethod(com.github.ambry.quota.QuotaMethod) Parameterized(org.junit.runners.Parameterized) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) Logger(org.slf4j.Logger) VerifiableProperties(com.github.ambry.config.VerifiableProperties) QuotaChargeCallback(com.github.ambry.quota.QuotaChargeCallback) Utils(com.github.ambry.utils.Utils) Test(org.junit.Test) Collectors(java.util.stream.Collectors) AccountStatsStore(com.github.ambry.accountstats.AccountStatsStore) QuotaUtils(com.github.ambry.quota.QuotaUtils) ExecutionException(java.util.concurrent.ExecutionException) AmbryQuotaManager(com.github.ambry.quota.AmbryQuotaManager) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) QuotaException(com.github.ambry.quota.QuotaException) QuotaMetrics(com.github.ambry.quota.QuotaMetrics) QuotaRecommendationMergePolicy(com.github.ambry.quota.QuotaRecommendationMergePolicy) QuotaName(com.github.ambry.quota.QuotaName) SimpleQuotaRecommendationMergePolicy(com.github.ambry.quota.SimpleQuotaRecommendationMergePolicy) MessageFormatRecord(com.github.ambry.messageformat.MessageFormatRecord) Assert(org.junit.Assert) RestRequest(com.github.ambry.rest.RestRequest) RetainingAsyncWritableChannel(com.github.ambry.commons.RetainingAsyncWritableChannel) ArrayList(java.util.ArrayList) AtomicLong(java.util.concurrent.atomic.AtomicLong) QuotaChargeCallback(com.github.ambry.quota.QuotaChargeCallback) QuotaException(com.github.ambry.quota.QuotaException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 5 with QuotaException

use of com.github.ambry.quota.QuotaException in project ambry by linkedin.

the class AmbryCUQuotaEnforcerTest method testRecommend.

@Test
public void testRecommend() throws Exception {
    // 1. Test that recommendation is serve when usage is within limit and correct quota is used based on rest method.
    QuotaRecommendation quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(QuotaTestUtils.createRestRequest(ACCOUNT, ACCOUNT.getAllContainers().iterator().next(), RestMethod.GET));
    assertEquals(QuotaName.READ_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(0, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.ALLOW);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(QuotaTestUtils.createRestRequest(ACCOUNT, ACCOUNT.getAllContainers().iterator().next(), RestMethod.POST));
    assertEquals(QuotaName.WRITE_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(0, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.ALLOW);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(QuotaTestUtils.createRestRequest(ACCOUNT, ACCOUNT.getAllContainers().iterator().next(), RestMethod.PUT));
    assertEquals(QuotaName.WRITE_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(0, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.ALLOW);
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(QuotaTestUtils.createRestRequest(ACCOUNT, ACCOUNT.getAllContainers().iterator().next(), RestMethod.DELETE));
    assertEquals(QuotaName.WRITE_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(0, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.ALLOW);
    // 2. Test that retryable QuotaException is thrown when quota not found.
    Account newAccount = ACCOUNT_SERVICE.generateRandomAccount(QuotaResourceType.ACCOUNT);
    try {
        AMBRY_QUOTA_ENFORCER.recommend(QuotaTestUtils.createRestRequest(newAccount, newAccount.getAllContainers().iterator().next(), RestMethod.GET));
        fail("QuotaException should be thrown when quota not found");
    } catch (QuotaException quotaException) {
        Assert.assertTrue(quotaException.isRetryable());
    }
    // 3. Test that recommendation is serve in case of any error.
    QUOTA_SOURCE.throwException = true;
    try {
        AMBRY_QUOTA_ENFORCER.recommend(QuotaTestUtils.createRestRequest(ACCOUNT, ACCOUNT.getAllContainers().iterator().next(), RestMethod.GET));
        fail("QuotaException should be thrown.");
    } catch (QuotaException quotaException) {
        Assert.assertTrue(quotaException.isRetryable());
    }
    QUOTA_SOURCE.throwException = false;
    // 4. Test that recommendation is deny when usage >= quota.
    Map<String, CapacityUnit> usageMap = QUOTA_SOURCE.getAllQuotaUsage();
    Map<String, CapacityUnit> quotaMap = QUOTA_SOURCE.getAllQuota();
    String id = String.valueOf(ACCOUNT.getId());
    usageMap.put(id, new CapacityUnit(quotaMap.get(id).getRcu() + 1, quotaMap.get(id).getWcu()));
    float usagePercentage = (float) (usageMap.get(id).getRcu() * 100) / quotaMap.get(id).getRcu();
    quotaRecommendation = AMBRY_QUOTA_ENFORCER.recommend(QuotaTestUtils.createRestRequest(ACCOUNT, ACCOUNT.getAllContainers().iterator().next(), RestMethod.GET));
    assertEquals(QuotaName.READ_CAPACITY_UNIT, quotaRecommendation.getQuotaName());
    assertEquals(usagePercentage, quotaRecommendation.getQuotaUsagePercentage(), 0.1);
    assertEquals(quotaRecommendation.getQuotaAction(), QuotaAction.DELAY);
}
Also used : Account(com.github.ambry.account.Account) QuotaException(com.github.ambry.quota.QuotaException) QuotaRecommendation(com.github.ambry.quota.QuotaRecommendation) Test(org.junit.Test)

Aggregations

QuotaException (com.github.ambry.quota.QuotaException)11 Test (org.junit.Test)7 QuotaResource (com.github.ambry.quota.QuotaResource)5 QuotaChargeCallback (com.github.ambry.quota.QuotaChargeCallback)4 QuotaName (com.github.ambry.quota.QuotaName)3 Account (com.github.ambry.account.Account)2 QuotaMethod (com.github.ambry.quota.QuotaMethod)2 QuotaRecommendation (com.github.ambry.quota.QuotaRecommendation)2 RestRequest (com.github.ambry.rest.RestRequest)2 MetricRegistry (com.codahale.metrics.MetricRegistry)1 AccountService (com.github.ambry.account.AccountService)1 Container (com.github.ambry.account.Container)1 AccountStatsStore (com.github.ambry.accountstats.AccountStatsStore)1 ByteBufferReadableStreamChannel (com.github.ambry.commons.ByteBufferReadableStreamChannel)1 RetainingAsyncWritableChannel (com.github.ambry.commons.RetainingAsyncWritableChannel)1 QuotaConfig (com.github.ambry.config.QuotaConfig)1 VerifiableProperties (com.github.ambry.config.VerifiableProperties)1 MessageFormatException (com.github.ambry.messageformat.MessageFormatException)1 MessageFormatRecord (com.github.ambry.messageformat.MessageFormatRecord)1 GetOption (com.github.ambry.protocol.GetOption)1