Search in sources :

Example 16 with RestMethod

use of com.github.ambry.rest.RestMethod in project ambry by linkedin.

the class AmbrySecurityServiceTest method processRequestTest.

/**
 * Tests {@link AmbrySecurityService#processRequest(RestRequest, Callback)} for common as well as uncommon cases
 * @throws Exception
 */
@Test
public void processRequestTest() throws Exception {
    // rest request being null
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.preProcessRequest(null).get(), null);
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processRequest(null).get(), null);
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.postProcessRequest(null).get(), null);
    // without callbacks
    RestMethod[] methods = new RestMethod[] { RestMethod.POST, RestMethod.GET, RestMethod.DELETE, RestMethod.HEAD, RestMethod.OPTIONS, RestMethod.PUT };
    for (RestMethod restMethod : methods) {
        RestRequest restRequest = createRestRequest(restMethod, "/", null);
        securityService.preProcessRequest(restRequest).get();
        securityService.processRequest(restRequest).get();
        securityService.postProcessRequest(restRequest).get();
    }
    // with GET sub resources
    for (RestUtils.SubResource subResource : RestUtils.SubResource.values()) {
        RestRequest restRequest = createRestRequest(RestMethod.GET, "/sampleId/" + subResource, null);
        Account account = InMemAccountService.UNKNOWN_ACCOUNT;
        insertAccountAndContainer(restRequest, account, account.getContainerById(Container.UNKNOWN_CONTAINER_ID));
        securityService.preProcessRequest(restRequest).get();
        securityService.processRequest(restRequest).get();
        securityService.postProcessRequest(restRequest).get();
    }
    // with UrlSigningService denying the request
    URL_SIGNING_SERVICE_FACTORY.isRequestSigned = true;
    URL_SIGNING_SERVICE_FACTORY.verifySignedRequestException = new RestServiceException("Msg", RestServiceErrorCode.Unauthorized);
    testExceptionCasesProcessRequest(createRestRequest(RestMethod.GET, "/", null), RestServiceErrorCode.Unauthorized, false);
    URL_SIGNING_SERVICE_FACTORY.isRequestSigned = false;
    // security service closed
    securityService.close();
    for (RestMethod restMethod : methods) {
        testExceptionCasesProcessRequest(createRestRequest(restMethod, "/", null), RestServiceErrorCode.ServiceUnavailable, true);
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) RestUtils(com.github.ambry.rest.RestUtils) RestMethod(com.github.ambry.rest.RestMethod) Test(org.junit.Test)

Example 17 with RestMethod

use of com.github.ambry.rest.RestMethod in project ambry by linkedin.

the class FrontendTestUrlSigningServiceFactory method verifyAccountAndContainerFromBlobId.

/**
 * Verifies presence of {@link Account} and {@link Container} injected into {@link RestRequest} using a
 * blobId string, for get/head/delete operations.
 * @param blobId The blobId string to get/head/delete.
 * @param expectedAccount The expected {@link Account} to verify its presence in {@link RestRequest}.
 * @param expectedContainer The expected {@link Container} to verify its presence in {@link RestRequest}.
 * @param expectedRestErrorCode The expected {@link RestServiceErrorCode} to verify.
 * @throws Exception
 */
private void verifyAccountAndContainerFromBlobId(String blobId, Account expectedAccount, Container expectedContainer, RestServiceErrorCode expectedRestErrorCode) throws Exception {
    if (blobId.startsWith("/")) {
        blobId = blobId.substring(1);
    }
    // PUT is verified in the tests of the individual handlers.
    for (RestMethod restMethod : Lists.newArrayList(RestMethod.GET, RestMethod.HEAD, RestMethod.DELETE)) {
        RestRequest restRequest = createRestRequest(restMethod, "/" + blobId, null, null);
        MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
        try {
            doOperation(restRequest, restResponseChannel);
            if (expectedRestErrorCode != null) {
                fail("Should have thrown");
            }
        } catch (RestServiceException e) {
            assertEquals("Wrong RestServiceErrorCode", expectedRestErrorCode, e.getErrorCode());
        }
        BlobId deserializedId = new BlobId(blobId, clusterMap);
        // Because BlobInfo is not fetched on deletes, V1 Blob IDs will never be reassigned to a known account/container.
        boolean alwaysExpectUnknown = restMethod == RestMethod.DELETE && deserializedId.getAccountId() == Account.UNKNOWN_ACCOUNT_ID && deserializedId.getContainerId() == Container.UNKNOWN_CONTAINER_ID;
        assertEquals("Wrong account object in RestRequest's args", alwaysExpectUnknown ? InMemAccountService.UNKNOWN_ACCOUNT : expectedAccount, restRequest.getArgs().get(RestUtils.InternalKeys.TARGET_ACCOUNT_KEY));
        assertEquals("Wrong container object in RestRequest's args", alwaysExpectUnknown ? Container.UNKNOWN_CONTAINER : expectedContainer, restRequest.getArgs().get(RestUtils.InternalKeys.TARGET_CONTAINER_KEY));
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) BlobId(com.github.ambry.commons.BlobId) RestMethod(com.github.ambry.rest.RestMethod)

Example 18 with RestMethod

use of com.github.ambry.rest.RestMethod 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)

Aggregations

RestMethod (com.github.ambry.rest.RestMethod)18 RestServiceException (com.github.ambry.rest.RestServiceException)11 RestRequest (com.github.ambry.rest.RestRequest)9 MockRestRequest (com.github.ambry.rest.MockRestRequest)8 Test (org.junit.Test)8 JSONObject (org.json.JSONObject)6 VerifiableProperties (com.github.ambry.config.VerifiableProperties)5 Properties (java.util.Properties)5 FrontendConfig (com.github.ambry.config.FrontendConfig)4 MockRestResponseChannel (com.github.ambry.rest.MockRestResponseChannel)4 RestUtils (com.github.ambry.rest.RestUtils)4 IOException (java.io.IOException)4 HashMap (java.util.HashMap)4 MetricRegistry (com.codahale.metrics.MetricRegistry)3 BlobId (com.github.ambry.commons.BlobId)3 BlobInfo (com.github.ambry.messageformat.BlobInfo)3 BlobProperties (com.github.ambry.messageformat.BlobProperties)3 RequestPath (com.github.ambry.rest.RequestPath)3 ByteBuffer (java.nio.ByteBuffer)3 Map (java.util.Map)3