Search in sources :

Example 56 with RestRequest

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

the class FrontendTestUrlSigningServiceFactory method badResponseHandlerAndRestRequestTest.

/**
 * Checks reactions of all methods in {@link FrontendRestRequestService} to bad {@link RestResponseHandler} and
 * {@link RestRequest} implementations.
 * @throws Exception
 */
@Test
public void badResponseHandlerAndRestRequestTest() throws Exception {
    // What happens inside FrontendRestRequestService during this test?
    // 1. Since the RestRequest throws errors, FrontendRestRequestService will attempt to submit response with exception
    // to FrontendTestResponseHandler.
    // 2. The submission will fail because FrontendTestResponseHandler has been shutdown.
    // 3. FrontendRestRequestService will directly complete the request over the RestResponseChannel with the *original*
    // exception.
    // 4. It will then try to release resources but closing the RestRequest will also throw an exception. This exception
    // is swallowed.
    // What the test is looking for -> No exceptions thrown when the handle is run and the original exception arrives
    // safely.
    responseHandler.shutdown();
    for (String methodName : new String[] { "handleGet", "handlePost", "handleHead", "handleDelete", "handleOptions", "handlePut" }) {
        Method method = FrontendRestRequestService.class.getDeclaredMethod(methodName, RestRequest.class, RestResponseChannel.class);
        responseHandler.reset();
        RestRequest restRequest = new BadRestRequest();
        MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
        method.invoke(frontendRestRequestService, restRequest, restResponseChannel);
        Exception e = restResponseChannel.getException();
        assertTrue("Unexpected exception", e instanceof IllegalStateException || e instanceof NullPointerException);
    }
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) RestMethod(com.github.ambry.rest.RestMethod) Method(java.lang.reflect.Method) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) JSONException(org.json.JSONException) InvocationTargetException(java.lang.reflect.InvocationTargetException) RestServiceException(com.github.ambry.rest.RestServiceException) IOException(java.io.IOException) RouterException(com.github.ambry.router.RouterException) URISyntaxException(java.net.URISyntaxException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AccountServiceException(com.github.ambry.account.AccountServiceException) Test(org.junit.Test) RestUtilsTest(com.github.ambry.rest.RestUtilsTest) StorageStatsUtilTest(com.github.ambry.server.StorageStatsUtilTest)

Example 57 with RestRequest

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

the class FrontendTestUrlSigningServiceFactory method getAndUseSignedUrlTest.

/**
 * Tests the handling of {@link Operations#GET_SIGNED_URL} requests.
 * @throws Exception
 */
@Test
public void getAndUseSignedUrlTest() throws Exception {
    // setup
    int contentLength = 10;
    ByteBuffer content = ByteBuffer.wrap(TestUtils.getRandomBytes(contentLength));
    long blobTtl = 7200;
    String serviceId = "getAndUseSignedUrlTest";
    String contentType = "application/octet-stream";
    String ownerId = "getAndUseSignedUrlTest";
    JSONObject headers = new JSONObject();
    headers.put(RestUtils.Headers.URL_TYPE, RestMethod.POST.name());
    setAmbryHeadersForPut(headers, blobTtl, !refContainer.isCacheable(), serviceId, contentType, ownerId, refAccount.getName(), refContainer.getName(), null);
    Map<String, String> userMetadata = new HashMap<>();
    userMetadata.put(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key1", "value1");
    userMetadata.put(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key2", "value2");
    RestUtilsTest.setUserMetadataHeaders(headers, userMetadata);
    // POST
    // Get signed URL
    RestRequest getSignedUrlRequest = createRestRequest(RestMethod.GET, Operations.GET_SIGNED_URL, headers, null);
    MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
    doOperation(getSignedUrlRequest, restResponseChannel);
    assertEquals("Account not as expected", refAccount, getSignedUrlRequest.getArgs().get(RestUtils.InternalKeys.TARGET_ACCOUNT_KEY));
    assertEquals("Container not as expected", refContainer, getSignedUrlRequest.getArgs().get(RestUtils.InternalKeys.TARGET_CONTAINER_KEY));
    assertEquals("Unexpected response status", ResponseStatus.Ok, restResponseChannel.getStatus());
    String signedPostUrl = restResponseChannel.getHeader(RestUtils.Headers.SIGNED_URL);
    assertNotNull("Did not get a signed POST URL", signedPostUrl);
    // Use signed URL to POST
    List<ByteBuffer> contents = new LinkedList<>();
    contents.add(content);
    contents.add(null);
    RestRequest postSignedRequest = createRestRequest(RestMethod.POST, signedPostUrl, null, contents);
    restResponseChannel = new MockRestResponseChannel();
    doOperation(postSignedRequest, restResponseChannel);
    String blobId = verifyPostAndReturnBlobId(postSignedRequest, restResponseChannel, refAccount, refContainer);
    // verify POST
    headers.put(RestUtils.Headers.BLOB_SIZE, contentLength);
    getBlobAndVerify(blobId, null, null, headers, content, refAccount, refContainer);
    getBlobInfoAndVerify(blobId, null, headers, refAccount, refContainer);
    // GET
    // Get signed URL
    JSONObject getHeaders = new JSONObject();
    getHeaders.put(RestUtils.Headers.URL_TYPE, RestMethod.GET.name());
    blobId = blobId.startsWith("/") ? blobId.substring(1) : blobId;
    getHeaders.put(RestUtils.Headers.BLOB_ID, blobId);
    getSignedUrlRequest = createRestRequest(RestMethod.GET, Operations.GET_SIGNED_URL, getHeaders, null);
    restResponseChannel = new MockRestResponseChannel();
    doOperation(getSignedUrlRequest, restResponseChannel);
    assertEquals("Account not as expected", refAccount, getSignedUrlRequest.getArgs().get(RestUtils.InternalKeys.TARGET_ACCOUNT_KEY));
    assertEquals("Container not as expected", refContainer, getSignedUrlRequest.getArgs().get(RestUtils.InternalKeys.TARGET_CONTAINER_KEY));
    assertEquals("Unexpected response status", ResponseStatus.Ok, restResponseChannel.getStatus());
    String signedGetUrl = restResponseChannel.getHeader(RestUtils.Headers.SIGNED_URL);
    assertNotNull("Did not get a signed GET URL", signedGetUrl);
    // Use URL to GET blob
    RestRequest getSignedRequest = createRestRequest(RestMethod.GET, signedGetUrl, null, null);
    restResponseChannel = new MockRestResponseChannel();
    doOperation(getSignedRequest, restResponseChannel);
    verifyGetBlobResponse(getSignedRequest, restResponseChannel, null, headers, content, refAccount, refContainer);
    // one error scenario to exercise exception path
    verifyOperationFailure(createRestRequest(RestMethod.GET, Operations.GET_SIGNED_URL, null, null), RestServiceErrorCode.MissingArgs);
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) HashMap(java.util.HashMap) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) ByteBuffer(java.nio.ByteBuffer) LinkedList(java.util.LinkedList) Test(org.junit.Test) RestUtilsTest(com.github.ambry.rest.RestUtilsTest) StorageStatsUtilTest(com.github.ambry.server.StorageStatsUtilTest)

Example 58 with RestRequest

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

the class FrontendTestUrlSigningServiceFactory method doConditionalUpdateAndDeleteTest.

/**
 * Tests blob conditional TTL update and DELETE operations on the given {@code container}.
 * @param expectedAccount the {@link Account} to use in post headers.
 * @param expectedContainer the {@link Container} to use in post headers.
 * @param serviceId the serviceId to use for the POST
 * @throws Exception
 */
private void doConditionalUpdateAndDeleteTest(Account expectedAccount, Container expectedContainer, String serviceId) throws Exception {
    PostResults postResults = prepareAndPostBlob(1024, serviceId, TTL_SECS, "application/octet-stream", "doConditionalUpdateAndDeleteTest", expectedAccount, expectedContainer, null);
    getBlobAndVerify(postResults.blobId, null, null, postResults.headers, postResults.content, expectedAccount, expectedContainer);
    getHeadAndVerify(postResults.blobId, null, null, postResults.headers, expectedAccount, expectedContainer);
    // failures
    Map<RestMethod, String> methodsToUris = new HashMap<>();
    methodsToUris.put(RestMethod.PUT, Operations.UPDATE_TTL);
    methodsToUris.put(RestMethod.DELETE, postResults.blobId);
    for (Map.Entry<RestMethod, String> methodToUri : methodsToUris.entrySet()) {
        RestMethod method = methodToUri.getKey();
        String uri = methodToUri.getValue();
        JSONObject badHeaders = new JSONObject();
        if (uri.equals(Operations.UPDATE_TTL)) {
            setUpdateTtlHeaders(badHeaders, postResults.blobId, serviceId);
        }
        // test Conditional op failure because only container name is set
        setAccountAndContainerHeaders(badHeaders, null, expectedContainer.getName());
        RestRequest restRequest = createRestRequest(method, uri, badHeaders, null);
        verifyOperationFailure(restRequest, RestServiceErrorCode.BadRequest);
        // test Conditional op failure because of incorrect account name
        setAccountAndContainerHeaders(badHeaders, "INCORRECT_ACCOUNT_NAME", expectedContainer.getName());
        restRequest = createRestRequest(method, uri, badHeaders, null);
        verifyOperationFailure(restRequest, RestServiceErrorCode.PreconditionFailed);
        // test Conditional op failure because of incorrect container name
        setAccountAndContainerHeaders(badHeaders, expectedAccount.getName(), "INCORRECT_CONTAINER_NAME");
        restRequest = createRestRequest(method, uri, badHeaders, null);
        verifyOperationFailure(restRequest, RestServiceErrorCode.PreconditionFailed);
    }
    // test success of conditional update
    updateBlobTtlAndVerify(postResults.blobId, postResults.headers, expectedAccount, expectedContainer, true);
    // test Conditional Delete succeeds
    deleteBlobAndVerify(postResults.blobId, postResults.headers, postResults.content, expectedAccount, expectedContainer, true);
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) HashMap(java.util.HashMap) Map(java.util.Map) HashMap(java.util.HashMap) ClusterMap(com.github.ambry.clustermap.ClusterMap) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) RestMethod(com.github.ambry.rest.RestMethod)

Example 59 with RestRequest

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

the class AmbrySecurityServiceTest method testExceptionCasesProcessResponse.

/**
 * Tests exception cases for
 * {@link SecurityService#processResponse(RestRequest, RestResponseChannel, BlobInfo, Callback)}
 * @param restMethod the {@link RestMethod} of the request to be made
 * @param restResponseChannel the {@link RestResponseChannel} to write responses over.
 * @param blobInfo the {@link BlobInfo} to be used for the {@link RestRequest}
 * @param expectedErrorCode the {@link RestServiceErrorCode} expected in the exception returned.
 * @throws Exception
 */
private void testExceptionCasesProcessResponse(RestMethod restMethod, RestResponseChannel restResponseChannel, BlobInfo blobInfo, RestServiceErrorCode expectedErrorCode) throws Exception {
    ThrowingConsumer<ExecutionException> errorAction = e -> {
        Assert.assertTrue("Exception should have been an instance of RestServiceException", e.getCause() instanceof RestServiceException);
        RestServiceException re = (RestServiceException) e.getCause();
        Assert.assertEquals("Unexpected RestServerErrorCode (Future)", expectedErrorCode, re.getErrorCode());
    };
    RestRequest restRequest = createRestRequest(restMethod, "/", null);
    TestUtils.assertException(ExecutionException.class, () -> securityService.processResponse(restRequest, restResponseChannel, blobInfo).get(), errorAction);
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) FrontendConfig(com.github.ambry.config.FrontendConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) Date(java.util.Date) URISyntaxException(java.net.URISyntaxException) ResponseStatus(com.github.ambry.rest.ResponseStatus) ByteBuffer(java.nio.ByteBuffer) ThrowingConsumer(com.github.ambry.utils.ThrowingConsumer) Future(java.util.concurrent.Future) JSONException(org.json.JSONException) JSONObject(org.json.JSONObject) HostThrottleConfig(com.github.ambry.config.HostThrottleConfig) TestUtils(com.github.ambry.utils.TestUtils) Locale(java.util.Locale) Map(java.util.Map) Container(com.github.ambry.account.Container) TimeZone(java.util.TimeZone) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) Utils(com.github.ambry.utils.Utils) BlobInfo(com.github.ambry.messageformat.BlobInfo) RestServiceException(com.github.ambry.rest.RestServiceException) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Account(com.github.ambry.account.Account) Callback(com.github.ambry.commons.Callback) RestUtils(com.github.ambry.rest.RestUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InMemAccountService(com.github.ambry.account.InMemAccountService) ByteRanges(com.github.ambry.router.ByteRanges) SimpleDateFormat(java.text.SimpleDateFormat) AccountService(com.github.ambry.account.AccountService) HashMap(java.util.HashMap) RestTestUtils(com.github.ambry.rest.RestTestUtils) QuotaManager(com.github.ambry.quota.QuotaManager) QuotaConfig(com.github.ambry.config.QuotaConfig) RequestPath(com.github.ambry.rest.RequestPath) QuotaMode(com.github.ambry.quota.QuotaMode) HostLevelThrottler(com.github.ambry.commons.HostLevelThrottler) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) Pair(com.github.ambry.utils.Pair) RestMethod(com.github.ambry.rest.RestMethod) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ByteRange(com.github.ambry.router.ByteRange) IOException(java.io.IOException) Test(org.junit.Test) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) InMemAccountServiceFactory(com.github.ambry.account.InMemAccountServiceFactory) AmbryQuotaManager(com.github.ambry.quota.AmbryQuotaManager) Mockito(org.mockito.Mockito) QuotaMetrics(com.github.ambry.quota.QuotaMetrics) SimpleQuotaRecommendationMergePolicy(com.github.ambry.quota.SimpleQuotaRecommendationMergePolicy) Assert(org.junit.Assert) RestRequest(com.github.ambry.rest.RestRequest) Collections(java.util.Collections) RestServiceException(com.github.ambry.rest.RestServiceException) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) ExecutionException(java.util.concurrent.ExecutionException)

Example 60 with RestRequest

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

Aggregations

RestRequest (com.github.ambry.rest.RestRequest)102 MockRestRequest (com.github.ambry.rest.MockRestRequest)82 MockRestResponseChannel (com.github.ambry.rest.MockRestResponseChannel)54 JSONObject (org.json.JSONObject)50 Test (org.junit.Test)46 RestServiceException (com.github.ambry.rest.RestServiceException)34 RestResponseChannel (com.github.ambry.rest.RestResponseChannel)26 RestMethod (com.github.ambry.rest.RestMethod)23 Account (com.github.ambry.account.Account)18 StorageStatsUtilTest (com.github.ambry.server.StorageStatsUtilTest)18 ExecutionException (java.util.concurrent.ExecutionException)18 ByteBuffer (java.nio.ByteBuffer)17 RestUtils (com.github.ambry.rest.RestUtils)16 RestUtilsTest (com.github.ambry.rest.RestUtilsTest)16 ReadableStreamChannel (com.github.ambry.router.ReadableStreamChannel)16 RestServiceErrorCode (com.github.ambry.rest.RestServiceErrorCode)15 MetricRegistry (com.codahale.metrics.MetricRegistry)14 Container (com.github.ambry.account.Container)14 RequestPath (com.github.ambry.rest.RequestPath)14 FutureResult (com.github.ambry.router.FutureResult)14