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);
}
}
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);
}
}
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());
}
}
}
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);
}
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());
}
}
Aggregations