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