Search in sources :

Example 1 with RestRequest

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

the class AmbrySecurityServiceTest method processResponseTest.

/**
 * Tests {@link AmbrySecurityService#processResponse(RestRequest, RestResponseChannel, BlobInfo, Callback)}  for
 * common as well as uncommon cases
 * @throws Exception
 */
@Test
public void processResponseTest() throws Exception {
    RestRequest restRequest = createRestRequest(RestMethod.GET, "/", null);
    // rest request being null
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processResponse(null, new MockRestResponseChannel(), DEFAULT_INFO).get(), null);
    // restResponseChannel being null
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processResponse(restRequest, null, DEFAULT_INFO).get(), null);
    // blob info being null
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processResponse(restRequest, new MockRestResponseChannel(), null).get(), null);
    // for unsupported methods
    RestMethod[] methods = { RestMethod.DELETE };
    for (RestMethod restMethod : methods) {
        testExceptionCasesProcessResponse(restMethod, new MockRestResponseChannel(), DEFAULT_INFO, RestServiceErrorCode.InternalServerError);
    }
    // OPTIONS (should be no errors)
    securityService.processResponse(createRestRequest(RestMethod.OPTIONS, "/", null), new MockRestResponseChannel(), null).get();
    // PUT (should be no errors)
    securityService.processResponse(createRestRequest(RestMethod.PUT, "/", null), new MockRestResponseChannel(), null).get();
    // GET signed URL (should be no errors)
    securityService.processResponse(createRestRequest(RestMethod.GET, Operations.GET_SIGNED_URL, null), new MockRestResponseChannel(), null).get();
    // HEAD
    // normal
    testHeadBlobWithVariousRanges(DEFAULT_INFO);
    // with lifeVersion
    testHeadBlobWithVariousRanges(LIFEVERSION_INFO);
    // unknown account
    testHeadBlobWithVariousRanges(UNKNOWN_INFO);
    // encrypted unknown account
    testHeadBlobWithVariousRanges(UNKNOWN_INFO_ENC);
    // with no owner id
    BlobInfo blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, null, "image/gif", false, Utils.Infinite_Time, REF_ACCOUNT.getId(), REF_CONTAINER.getId(), false, null, null, null), new byte[0]);
    testHeadBlobWithVariousRanges(blobInfo);
    // with no content type
    blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, null, false, Utils.Infinite_Time, REF_ACCOUNT.getId(), REF_CONTAINER.getId(), false, null, null, null), new byte[0]);
    testHeadBlobWithVariousRanges(blobInfo);
    // with a TTL
    blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, REF_ACCOUNT.getId(), REF_CONTAINER.getId(), false, null, null, null), new byte[0]);
    testHeadBlobWithVariousRanges(blobInfo);
    // GET BlobInfo
    testGetSubResource(DEFAULT_INFO, RestUtils.SubResource.BlobInfo);
    testGetSubResource(LIFEVERSION_INFO, RestUtils.SubResource.BlobInfo);
    testGetSubResource(UNKNOWN_INFO, RestUtils.SubResource.BlobInfo);
    testGetSubResource(UNKNOWN_INFO, RestUtils.SubResource.BlobInfo);
    testGetSubResource(UNKNOWN_INFO_ENC, RestUtils.SubResource.BlobInfo);
    // GET UserMetadata
    testGetSubResource(DEFAULT_INFO, RestUtils.SubResource.UserMetadata);
    byte[] usermetadata = TestUtils.getRandomBytes(10);
    testGetSubResource(new BlobInfo(DEFAULT_INFO.getBlobProperties(), usermetadata), RestUtils.SubResource.UserMetadata);
    // POST
    testPostBlob();
    // GET Blob
    testGetBlobWithVariousRanges(LIFEVERSION_INFO);
    // less than chunk threshold size
    blobInfo = new BlobInfo(new BlobProperties(FRONTEND_CONFIG.chunkedGetResponseThresholdInBytes - 1, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null, null, null), new byte[0]);
    testGetBlobWithVariousRanges(blobInfo);
    // == chunk threshold size
    blobInfo = new BlobInfo(new BlobProperties(FRONTEND_CONFIG.chunkedGetResponseThresholdInBytes, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null, null, null), new byte[0]);
    testGetBlobWithVariousRanges(blobInfo);
    // more than chunk threshold size
    blobInfo = new BlobInfo(new BlobProperties(FRONTEND_CONFIG.chunkedGetResponseThresholdInBytes * 2, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null, null, null), new byte[0]);
    testGetBlobWithVariousRanges(blobInfo);
    // Get blob with content type null
    blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, null, true, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null, null, null), new byte[0]);
    testGetBlobWithVariousRanges(blobInfo);
    // Get blob in a non-cacheable container. AmbrySecurityService should not care about the isPrivate setting.
    blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, "image/gif", false, Utils.Infinite_Time, Account.UNKNOWN_ACCOUNT_ID, Container.DEFAULT_PRIVATE_CONTAINER_ID, false, null, null, null), new byte[0]);
    testGetBlobWithVariousRanges(blobInfo);
    // Get blob in a cacheable container. AmbrySecurityService should not care about the isPrivate setting.
    blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, "image/gif", true, Utils.Infinite_Time, Account.UNKNOWN_ACCOUNT_ID, Container.DEFAULT_PUBLIC_CONTAINER_ID, false, null, null, null), new byte[0]);
    testGetBlobWithVariousRanges(blobInfo);
    // not modified response
    // > creation time (in secs).
    testGetNotModifiedBlob(blobInfo, blobInfo.getBlobProperties().getCreationTimeInMs() + 1000);
    // == creation time
    testGetNotModifiedBlob(blobInfo, blobInfo.getBlobProperties().getCreationTimeInMs());
    // < creation time (in secs)
    testGetNotModifiedBlob(blobInfo, blobInfo.getBlobProperties().getCreationTimeInMs() - 1000);
    // Get blob for a public blob with content type as "text/html"
    blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, "text/html", true, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null, null, null), new byte[0]);
    testGetBlobWithVariousRanges(blobInfo);
    // not modified response
    // > creation time (in secs).
    testGetNotModifiedBlob(DEFAULT_INFO, DEFAULT_INFO.getBlobProperties().getCreationTimeInMs() + 1000);
    // == creation time
    testGetNotModifiedBlob(DEFAULT_INFO, DEFAULT_INFO.getBlobProperties().getCreationTimeInMs());
    // < creation time (in secs)
    testGetNotModifiedBlob(DEFAULT_INFO, DEFAULT_INFO.getBlobProperties().getCreationTimeInMs() - 1000);
    // bad rest response channel
    testExceptionCasesProcessResponse(RestMethod.HEAD, new BadRestResponseChannel(), blobInfo, RestServiceErrorCode.InternalServerError);
    testExceptionCasesProcessResponse(RestMethod.GET, new BadRestResponseChannel(), blobInfo, RestServiceErrorCode.InternalServerError);
    testExceptionCasesProcessResponse(RestMethod.POST, new BadRestResponseChannel(), blobInfo, RestServiceErrorCode.InternalServerError);
    // security service closed
    securityService.close();
    methods = new RestMethod[] { RestMethod.POST, RestMethod.GET, RestMethod.DELETE, RestMethod.HEAD };
    for (RestMethod restMethod : methods) {
        testExceptionCasesProcessResponse(restMethod, new MockRestResponseChannel(), blobInfo, RestServiceErrorCode.ServiceUnavailable);
    }
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) BlobProperties(com.github.ambry.messageformat.BlobProperties) BlobInfo(com.github.ambry.messageformat.BlobInfo) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) RestMethod(com.github.ambry.rest.RestMethod) Test(org.junit.Test)

Example 2 with RestRequest

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

the class AmbrySecurityServiceTest method testGetNotModifiedBlob.

/**
 * Tests {@link SecurityService#processResponse(RestRequest, RestResponseChannel, BlobInfo, Callback)} for a Get blob
 * with the passed in {@link BlobInfo} for a not modified response
 * @param blobInfo the {@link BlobInfo} to be used for the {@link RestRequest}
 * @param ifModifiedSinceMs the value (as a date string) of the {@link RestUtils.Headers#IF_MODIFIED_SINCE} header.
 * @throws Exception
 */
private void testGetNotModifiedBlob(BlobInfo blobInfo, long ifModifiedSinceMs) throws Exception {
    MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
    JSONObject headers = new JSONObject();
    SimpleDateFormat dateFormat = new SimpleDateFormat(RestUtils.HTTP_DATE_FORMAT, Locale.ENGLISH);
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    Date date = new Date(ifModifiedSinceMs);
    String dateStr = dateFormat.format(date);
    headers.put(RestUtils.Headers.IF_MODIFIED_SINCE, dateStr);
    RestRequest restRequest = createRestRequest(RestMethod.GET, "/abc", headers);
    Pair<Account, Container> accountAndContainer = getAccountAndContainer(blobInfo.getBlobProperties());
    insertAccountAndContainer(restRequest, accountAndContainer.getFirst(), accountAndContainer.getSecond());
    securityService.processResponse(restRequest, restResponseChannel, blobInfo).get();
    if (ifModifiedSinceMs >= blobInfo.getBlobProperties().getCreationTimeInMs()) {
        Assert.assertEquals("Not modified response expected", ResponseStatus.NotModified, restResponseChannel.getStatus());
        verifyHeadersForGetBlobNotModified(restResponseChannel, accountAndContainer.getSecond().isCacheable());
    } else {
        Assert.assertEquals("Not modified response should not be returned", ResponseStatus.Ok, restResponseChannel.getStatus());
        verifyHeadersForGetBlob(restRequest, blobInfo, accountAndContainer, null, restResponseChannel);
    }
}
Also used : Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) SimpleDateFormat(java.text.SimpleDateFormat) Date(java.util.Date)

Example 3 with RestRequest

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

the class AmbrySecurityServiceTest method postProcessQuotaManagerTest.

/**
 * {@link AmbrySecurityService#postProcessRequest(RestRequest, Callback)})} should throw RestServiceException if rate
 * is more than expected. RestServiceErrorCode.TooManyRequests is expected in this case.
 */
@Test
public void postProcessQuotaManagerTest() throws Exception {
    HostLevelThrottler quotaManager = Mockito.mock(HostLevelThrottler.class);
    AmbrySecurityService ambrySecurityService = new AmbrySecurityService(new FrontendConfig(new VerifiableProperties(new Properties())), new FrontendMetrics(new MetricRegistry()), URL_SIGNING_SERVICE_FACTORY.getUrlSigningService(), quotaManager, QUOTA_MANAGER);
    // Everything should be good.
    Mockito.when(quotaManager.shouldThrottle(any())).thenReturn(false);
    for (int i = 0; i < 100; i++) {
        for (RestMethod restMethod : RestMethod.values()) {
            RestRequest restRequest = createRestRequest(restMethod, "/", null);
            ambrySecurityService.postProcessRequest(restRequest).get();
        }
    }
    // Requests should be denied.
    Mockito.when(quotaManager.shouldThrottle(any())).thenReturn(true);
    for (RestMethod restMethod : RestMethod.values()) {
        RestRequest restRequest = createRestRequest(restMethod, "/", null);
        try {
            ambrySecurityService.postProcessRequest(restRequest).get();
            Assert.fail("Should have failed.");
        } catch (Exception e) {
            Assert.assertEquals("Exception should be TooManyRequests", RestServiceErrorCode.TooManyRequests, ((RestServiceException) e.getCause()).getErrorCode());
        }
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) FrontendConfig(com.github.ambry.config.FrontendConfig) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) VerifiableProperties(com.github.ambry.config.VerifiableProperties) HostLevelThrottler(com.github.ambry.commons.HostLevelThrottler) MetricRegistry(com.codahale.metrics.MetricRegistry) BlobProperties(com.github.ambry.messageformat.BlobProperties) Properties(java.util.Properties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) URISyntaxException(java.net.URISyntaxException) JSONException(org.json.JSONException) RestServiceException(com.github.ambry.rest.RestServiceException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) RestMethod(com.github.ambry.rest.RestMethod) Test(org.junit.Test)

Example 4 with RestRequest

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

the class AmbrySecurityServiceTest method testGetBlob.

/**
 * Tests {@link SecurityService#processResponse(RestRequest, RestResponseChannel, BlobInfo, Callback)} for a Get blob
 * with the passed in {@link BlobInfo} and {@link ByteRange}
 * @param blobInfo the {@link BlobInfo} to be used for the {@link RestRequest}
 * @param range the {@link ByteRange} for the {@link RestRequest}
 * @throws Exception
 */
private void testGetBlob(BlobInfo blobInfo, ByteRange range) throws Exception {
    MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
    JSONObject headers = range != null ? new JSONObject().put(RestUtils.Headers.RANGE, RestTestUtils.getRangeHeaderString(range)) : null;
    RestRequest restRequest = createRestRequest(RestMethod.GET, "/", headers);
    Pair<Account, Container> accountAndContainer = getAccountAndContainer(blobInfo.getBlobProperties());
    insertAccountAndContainer(restRequest, accountAndContainer.getFirst(), accountAndContainer.getSecond());
    securityService.processResponse(restRequest, restResponseChannel, blobInfo).get();
    Assert.assertEquals("ProcessResponse status should have been set", range == null ? ResponseStatus.Ok : ResponseStatus.PartialContent, restResponseChannel.getStatus());
    verifyHeadersForGetBlob(restRequest, blobInfo, accountAndContainer, range, restResponseChannel);
}
Also used : Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel)

Example 5 with RestRequest

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

the class FrontendTestUrlSigningServiceFactory method doRuntimeExceptionRouterTest.

// runtimeExceptionRouterTest() helpers
/**
 * Tests reactions of various methods of {@link FrontendRestRequestService} to a {@link Router} that throws
 * {@link RuntimeException}.
 * @param restMethod used to determine the method to invoke in {@link FrontendRestRequestService}.
 * @throws Exception
 */
private void doRuntimeExceptionRouterTest(RestMethod restMethod) throws Exception {
    RestRequest restRequest = createRestRequest(restMethod, referenceBlobIdStr, null, null);
    RestResponseChannel restResponseChannel = new MockRestResponseChannel();
    try {
        switch(restMethod) {
            case GET:
            case DELETE:
            case HEAD:
                doOperation(restRequest, restResponseChannel);
                fail(restMethod + " should have detected a RestServiceException because of a bad router");
                break;
            case POST:
                JSONObject headers = new JSONObject();
                setAmbryHeadersForPut(headers, Utils.Infinite_Time, !refContainer.isCacheable(), "test-serviceID", "text/plain", "test-ownerId", refAccount.getName(), refContainer.getName(), null);
                restRequest = createRestRequest(restMethod, "/", headers, null);
                doOperation(restRequest, restResponseChannel);
                fail("POST should have detected a RestServiceException because of a bad router");
                break;
            default:
                throw new IllegalArgumentException("Unrecognized RestMethod: " + restMethod);
        }
    } catch (RuntimeException e) {
        assertEquals("Unexpected error message", InMemoryRouter.OPERATION_THROW_EARLY_RUNTIME_EXCEPTION, e.getMessage());
    }
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel)

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