Search in sources :

Example 6 with GetBlobOptionsBuilder

use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.

the class RouterStoreTest method testSizeLimitInList.

/**
 * Test when the number of updates exceeds the maximum number of versions to save. RouterStore should start removing
 * the old blobs.
 */
@Test
public void testSizeLimitInList() throws Exception {
    RouterStore store = new RouterStore(accountServiceMetrics, backup, helixStore, new AtomicReference<>(router), forBackfill, TOTAL_NUMBER_OF_VERSION_TO_KEEP, config);
    Map<Short, Account> idToRefAccountMap = new HashMap<>();
    Map<Short, Map<Short, Container>> idtoRefContainerMap = new HashMap<>();
    Set<Short> accountIDSet = new HashSet<>();
    for (int i = 0; i < TOTAL_NUMBER_OF_VERSION_TO_KEEP; i++) {
        // generate an new account and test update and fetch on this account
        Map<Short, Account> newIdToRefAccountMap = new HashMap<>();
        AccountTestUtils.generateRefAccounts(newIdToRefAccountMap, idtoRefContainerMap, accountIDSet, 1, 1);
        if (!forBackfill) {
            for (Map.Entry<Short, Account> entry : newIdToRefAccountMap.entrySet()) {
                idToRefAccountMap.put(entry.getKey(), entry.getValue());
            }
        } else {
            idToRefAccountMap = newIdToRefAccountMap;
        }
        assertUpdateAndFetch(store, idToRefAccountMap, newIdToRefAccountMap, i + 1, i + 1);
    }
    // Now we already have maximum number of versions in the list, adding a new version should remove the oldest one.
    List<RouterStore.BlobIDAndVersion> blobIDAndVersions = getBlobIDAndVersionInHelix(TOTAL_NUMBER_OF_VERSION_TO_KEEP);
    Collections.sort(blobIDAndVersions, Comparator.comparing(RouterStore.BlobIDAndVersion::getVersion));
    assertEquals(1, blobIDAndVersions.get(0).getVersion());
    Map<Short, Account> newIdToRefAccountMap = new HashMap<>();
    AccountTestUtils.generateRefAccounts(newIdToRefAccountMap, idtoRefContainerMap, accountIDSet, 1, 1);
    if (!forBackfill) {
        for (Map.Entry<Short, Account> entry : newIdToRefAccountMap.entrySet()) {
            idToRefAccountMap.put(entry.getKey(), entry.getValue());
        }
    } else {
        idToRefAccountMap = newIdToRefAccountMap;
    }
    assertUpdateAndFetch(store, idToRefAccountMap, newIdToRefAccountMap, TOTAL_NUMBER_OF_VERSION_TO_KEEP + 1, TOTAL_NUMBER_OF_VERSION_TO_KEEP);
    // Get the list again and compare the blob ids
    List<RouterStore.BlobIDAndVersion> blobIDAndVersionsAfterUpdate = getBlobIDAndVersionInHelix(TOTAL_NUMBER_OF_VERSION_TO_KEEP);
    Collections.sort(blobIDAndVersionsAfterUpdate, Comparator.comparing(RouterStore.BlobIDAndVersion::getVersion));
    assertEquals("First version should be removed", 2, blobIDAndVersionsAfterUpdate.get(0).getVersion());
    assertEquals("Version mismatch", TOTAL_NUMBER_OF_VERSION_TO_KEEP + 1, blobIDAndVersionsAfterUpdate.get(TOTAL_NUMBER_OF_VERSION_TO_KEEP - 1).getVersion());
    for (int i = 1; i < TOTAL_NUMBER_OF_VERSION_TO_KEEP; i++) {
        assertEquals("BlobIDAndVersion mismatch at index " + i, blobIDAndVersions.get(i), blobIDAndVersionsAfterUpdate.get(i - 1));
    }
    try {
        router.getBlob(blobIDAndVersions.get(0).getBlobID(), new GetBlobOptionsBuilder().build()).get();
        fail("Expecting not found exception");
    } catch (ExecutionException e) {
        Throwable t = e.getCause();
        assertTrue("Cause should be RouterException", t instanceof RouterException);
        assertEquals("ErrorCode mismatch", RouterErrorCode.BlobDoesNotExist, ((RouterException) t).getErrorCode());
    }
}
Also used : GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder) RouterException(com.github.ambry.router.RouterException) HashMap(java.util.HashMap) ExecutionException(java.util.concurrent.ExecutionException) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 7 with GetBlobOptionsBuilder

use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.

the class MockHeadCallback method handleGet.

@Override
public void handleGet(RestRequest restRequest, RestResponseChannel restResponseChannel) {
    if (shouldProceed(restRequest, restResponseChannel)) {
        String blobId = getBlobId(restRequest);
        MockGetCallback callback = new MockGetCallback(this, restRequest, restResponseChannel);
        router.getBlob(blobId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.All).build(), callback, null);
    }
}
Also used : GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder)

Example 8 with GetBlobOptionsBuilder

use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.

the class FrontendRestRequestService method securityPostProcessRequestCallback.

/**
 * Build a callback to use for {@link SecurityService#postProcessRequest}. This callback forwards request to the
 * {@link Router} once ID conversion is completed. In the case of some sub-resources
 * (e.g., {@link SubResource#Replicas}), the request is completed and not forwarded to the {@link Router}.
 * @param convertedId the converted blob ID to use in router requests.
 * @param restRequest the {@link RestRequest}.
 * @param restResponseChannel the {@link RestResponseChannel}.
 * @param getCallback the {@link GetCallback} to use if this is a {@link RestMethod#GET} request, or null for other
 *                    request types.
 * @param headCallback the {@link HeadCallback} to use if this is a {@link RestMethod#HEAD} request, or null for other
 *                    request types.
 * @param deleteCallback the {@link DeleteCallback} to use if this is a {@link RestMethod#DELETE} request, or null for
 *                       other request types.
 * @return the {@link Callback} to use.
 */
private Callback<Void> securityPostProcessRequestCallback(String convertedId, RestRequest restRequest, RestResponseChannel restResponseChannel, GetCallback getCallback, HeadCallback headCallback, DeleteCallback deleteCallback) {
    Callback<ReadableStreamChannel> completionCallback = (result, exception) -> submitResponse(restRequest, restResponseChannel, result, exception);
    RestMethod restMethod = restRequest.getRestMethod();
    AsyncOperationTracker.Metrics metrics;
    switch(restMethod) {
        case GET:
            metrics = frontendMetrics.getSecurityPostProcessRequestMetrics;
            break;
        case HEAD:
            metrics = frontendMetrics.headSecurityPostProcessRequestMetrics;
            break;
        case DELETE:
            metrics = frontendMetrics.deleteSecurityPostProcessRequestMetrics;
            break;
        default:
            throw new IllegalStateException("Unrecognized RestMethod: " + restMethod);
    }
    return FrontendUtils.buildCallback(metrics, result -> {
        ReadableStreamChannel response = null;
        switch(restMethod) {
            case GET:
                SubResource subResource = getRequestPath(restRequest).getSubResource();
                // inject encryption metrics if need be
                if (BlobId.isEncrypted(convertedId)) {
                    RestRequestMetrics restRequestMetrics = getMetricsGroupForGet(frontendMetrics, subResource).getRestRequestMetrics(restRequest.isSslUsed(), true);
                    restRequest.getMetricsTracker().injectMetrics(restRequestMetrics);
                }
                if (subResource == null) {
                    getCallback.markStartTime();
                    router.getBlob(convertedId, getCallback.options, getCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, true));
                } else {
                    switch(subResource) {
                        case BlobInfo:
                        case UserMetadata:
                        case Segment:
                            getCallback.markStartTime();
                            router.getBlob(convertedId, getCallback.options, getCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, true));
                            break;
                        case Replicas:
                            response = getReplicasHandler.getReplicas(convertedId, restResponseChannel);
                            break;
                    }
                }
                break;
            case HEAD:
                GetOption getOption = getGetOption(restRequest, frontendConfig.defaultRouterGetOption);
                // inject encryption metrics if need be
                if (BlobId.isEncrypted(convertedId)) {
                    RestRequestMetrics requestMetrics = frontendMetrics.headBlobMetricsGroup.getRestRequestMetrics(restRequest.isSslUsed(), true);
                    restRequest.getMetricsTracker().injectMetrics(requestMetrics);
                }
                headCallback.markStartTime();
                router.getBlob(convertedId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.BlobInfo).getOption(getOption).restRequest(restRequest).build(), headCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, false));
                break;
            case DELETE:
                deleteCallback.markStartTime();
                router.deleteBlob(convertedId, getHeader(restRequest.getArgs(), Headers.SERVICE_ID, false), deleteCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, false));
                break;
            default:
                throw new IllegalStateException("Unrecognized RestMethod: " + restMethod);
        }
        if (response != null) {
            completionCallback.onCompletion(response, null);
        }
    }, restRequest.getUri(), logger, completionCallback);
}
Also used : Histogram(com.codahale.metrics.Histogram) GetOption(com.github.ambry.protocol.GetOption) FrontendConfig(com.github.ambry.config.FrontendConfig) ResponseStatus(com.github.ambry.rest.ResponseStatus) LoggerFactory(org.slf4j.LoggerFactory) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) AccountService(com.github.ambry.account.AccountService) QuotaManager(com.github.ambry.quota.QuotaManager) ByteBuffer(java.nio.ByteBuffer) ThrowingConsumer(com.github.ambry.utils.ThrowingConsumer) RequestPath(com.github.ambry.rest.RequestPath) NamedBlobDb(com.github.ambry.named.NamedBlobDb) RestRequestService(com.github.ambry.rest.RestRequestService) RestRequestMetrics(com.github.ambry.rest.RestRequestMetrics) SystemTime(com.github.ambry.utils.SystemTime) Router(com.github.ambry.router.Router) RouterErrorCode(com.github.ambry.router.RouterErrorCode) RestResponseHandler(com.github.ambry.rest.RestResponseHandler) ReadableStreamChannel(com.github.ambry.router.ReadableStreamChannel) Logger(org.slf4j.Logger) GregorianCalendar(java.util.GregorianCalendar) RestMethod(com.github.ambry.rest.RestMethod) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) InternalKeys(com.github.ambry.rest.RestUtils.InternalKeys) ClusterMap(com.github.ambry.clustermap.ClusterMap) Utils(com.github.ambry.utils.Utils) IOException(java.io.IOException) GetBlobOptions(com.github.ambry.router.GetBlobOptions) RouterException(com.github.ambry.router.RouterException) BlobInfo(com.github.ambry.messageformat.BlobInfo) QuotaUtils(com.github.ambry.quota.QuotaUtils) AccountStatsStore(com.github.ambry.accountstats.AccountStatsStore) RestServiceException(com.github.ambry.rest.RestServiceException) GetBlobResult(com.github.ambry.router.GetBlobResult) Callback(com.github.ambry.commons.Callback) RestUtils(com.github.ambry.rest.RestUtils) AsyncOperationTracker(com.github.ambry.utils.AsyncOperationTracker) RestRequest(com.github.ambry.rest.RestRequest) GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder) BlobId(com.github.ambry.commons.BlobId) GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) ReadableStreamChannel(com.github.ambry.router.ReadableStreamChannel) RestRequestMetrics(com.github.ambry.rest.RestRequestMetrics) GetOption(com.github.ambry.protocol.GetOption) AsyncOperationTracker(com.github.ambry.utils.AsyncOperationTracker) RestMethod(com.github.ambry.rest.RestMethod)

Example 9 with GetBlobOptionsBuilder

use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.

the class RouterServerTestFramework method startGetBlob.

/**
 * Submit a getBlob operation.
 * @param options the {@link GetOption} associated with the request.
 * @param checkDeleted {@code true}, checks that the blob is deleted.
 * @param opChain the {@link OperationChain} object that this operation is a part of.
 */
private void startGetBlob(GetOption options, final boolean checkDeleted, final OperationChain opChain) {
    Callback<GetBlobResult> callback = new TestCallback<>(opChain, checkDeleted);
    Future<GetBlobResult> future = router.getBlob(opChain.blobId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.All).getOption(options).build(), callback, quotaChargeCallback);
    TestFuture<GetBlobResult> testFuture = new TestFuture<GetBlobResult>(future, genLabel("getBlob", checkDeleted), opChain) {

        @Override
        void check() throws Exception {
            if (checkDeleted) {
                checkDeleted();
            } else {
                GetBlobResult result = get();
                checkBlobInfo(result.getBlobInfo(), opChain, getOperationName());
                checkBlob(result.getBlobDataChannel(), opChain, getOperationName());
            }
        }
    };
    opChain.testFutures.add(testFuture);
}
Also used : GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder) GetBlobResult(com.github.ambry.router.GetBlobResult)

Example 10 with GetBlobOptionsBuilder

use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.

the class RouterServerTestFramework method startGetBlobAuthorizationFailTest.

/**
 * Submit a getBlob operation with incorrect accountId/ContainerId in blobId.
 * @param opChain the {@link OperationChain} object that this operation is a part of.
 */
private void startGetBlobAuthorizationFailTest(final OperationChain opChain) {
    Callback<GetBlobResult> callback = new TestCallback<>(opChain, true);
    BlobId originalId, fraudId;
    try {
        originalId = new BlobId(opChain.blobId, clusterMap);
        fraudId = BlobId.craft(originalId, originalId.getVersion(), (short) (originalId.getAccountId() + 1), (short) (originalId.getContainerId() + 1));
    } catch (IOException e) {
        // If there is a blobId creation failure, throw the exception and don't need to do actual action.
        FutureResult<Void> future = new FutureResult<>();
        // continue the chain
        future.done(null, e);
        callback.onCompletion(null, e);
        TestFuture<Void> testFuture = new TestFuture<Void>(future, genLabel("getBlobAuthorizationFail", true), opChain) {

            @Override
            void check() throws Exception {
                throw e;
            }
        };
        opChain.testFutures.add(testFuture);
        return;
    }
    // If everything good:
    Future<GetBlobResult> future = router.getBlob(fraudId.getID(), new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.All).getOption(GetOption.Include_All).build(), callback, quotaChargeCallback);
    TestFuture<GetBlobResult> testFuture = new TestFuture<GetBlobResult>(future, genLabel("getBlobAuthorizationFail", true), opChain) {

        @Override
        void check() throws Exception {
            checkExpectedRouterErrorCode(RouterErrorCode.BlobAuthorizationFailure);
        }
    };
    opChain.testFutures.add(testFuture);
}
Also used : GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder) GetBlobResult(com.github.ambry.router.GetBlobResult) IOException(java.io.IOException) IOException(java.io.IOException) RouterException(com.github.ambry.router.RouterException) ExecutionException(java.util.concurrent.ExecutionException) FutureResult(com.github.ambry.router.FutureResult) BlobId(com.github.ambry.commons.BlobId)

Aggregations

GetBlobOptionsBuilder (com.github.ambry.router.GetBlobOptionsBuilder)11 GetBlobResult (com.github.ambry.router.GetBlobResult)6 RouterException (com.github.ambry.router.RouterException)4 ExecutionException (java.util.concurrent.ExecutionException)3 BlobId (com.github.ambry.commons.BlobId)2 ByteBufferReadableStreamChannel (com.github.ambry.commons.ByteBufferReadableStreamChannel)2 RestResponseChannel (com.github.ambry.rest.RestResponseChannel)2 ReadableStreamChannel (com.github.ambry.router.ReadableStreamChannel)2 IOException (java.io.IOException)2 Histogram (com.codahale.metrics.Histogram)1 AccountService (com.github.ambry.account.AccountService)1 AccountStatsStore (com.github.ambry.accountstats.AccountStatsStore)1 ClusterMap (com.github.ambry.clustermap.ClusterMap)1 Callback (com.github.ambry.commons.Callback)1 ReadableStreamChannelInputStream (com.github.ambry.commons.ReadableStreamChannelInputStream)1 RetainingAsyncWritableChannel (com.github.ambry.commons.RetainingAsyncWritableChannel)1 FrontendConfig (com.github.ambry.config.FrontendConfig)1 BlobInfo (com.github.ambry.messageformat.BlobInfo)1 PutMessageFormatInputStream (com.github.ambry.messageformat.PutMessageFormatInputStream)1 NamedBlobDb (com.github.ambry.named.NamedBlobDb)1