use of com.github.ambry.rest.RestMethod in project ambry by linkedin.
the class FrontendTestUrlSigningServiceFactory method doRouterExceptionPipelineTest.
// routerExceptionPipelineTest() helpers.
/**
* Does the exception pipelining test for {@link Router}.
* @param testRouter the {@link Router} to use to while creating {@link FrontendRestRequestService}.
* @param exceptionMsg the expected exception message.
* @throws Exception
*/
private void doRouterExceptionPipelineTest(FrontendTestRouter testRouter, String exceptionMsg) throws Exception {
frontendRestRequestService = new FrontendRestRequestService(frontendConfig, frontendMetrics, testRouter, clusterMap, idConverterFactory, securityServiceFactory, urlSigningService, idSigningService, null, accountService, accountAndContainerInjector, datacenterName, hostname, clusterName, accountStatsStore, QUOTA_MANAGER);
frontendRestRequestService.setupResponseHandler(responseHandler);
frontendRestRequestService.start();
for (RestMethod restMethod : RestMethod.values()) {
switch(restMethod) {
case HEAD:
testRouter.exceptionOpType = FrontendTestRouter.OpType.GetBlob;
checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, referenceBlobIdStr, null, null));
break;
case GET:
testRouter.exceptionOpType = FrontendTestRouter.OpType.GetBlob;
checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, referenceBlobIdStr, null, null));
break;
case POST:
testRouter.exceptionOpType = FrontendTestRouter.OpType.PutBlob;
JSONObject headers = new JSONObject();
setAmbryHeadersForPut(headers, 7200, !refContainer.isCacheable(), "routerExceptionPipelineTest", "application/octet-stream", "routerExceptionPipelineTest", refAccount.getName(), refContainer.getName(), null);
checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, "/", headers, null));
break;
case DELETE:
testRouter.exceptionOpType = FrontendTestRouter.OpType.DeleteBlob;
checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, referenceBlobIdStr, null, null));
break;
default:
break;
}
}
}
use of com.github.ambry.rest.RestMethod in project ambry by linkedin.
the class ThresholdsTest method defaultPerformanceConfigTest.
/**
* Test that {@link PerformanceConfig} can correctly populate thresholds with default value. This is to ensure JSONObject
* can parse the long value from default strings.
*/
@Test
public void defaultPerformanceConfigTest() {
// purposely use empty properties to make config use default value
VerifiableProperties properties = new VerifiableProperties(new Properties());
PerformanceConfig config = new PerformanceConfig(properties);
for (RestMethod method : EnumSet.of(RestMethod.GET, RestMethod.DELETE, RestMethod.POST, RestMethod.HEAD, RestMethod.PUT)) {
Criteria criteria = config.nonSuccessRequestThresholds.get(method).getCriteria(PerformanceIndex.RoundTripTime);
assertEquals("Threshold value is not as expected", criteria.getThresholdValue(), Long.MAX_VALUE);
}
// verify default GET time to first byte is Long.MAX_VALUE
assertEquals("Threshold value is not as expected", config.successGetTimeToFirstByteThreshold, Long.MAX_VALUE);
// verify default GET/POST average bandwidth is 0
assertEquals("Threshold value is not as expected", config.successGetAverageBandwidthThreshold, 0);
assertEquals("Threshold value is not as expected", config.successPostAverageBandwidthThreshold, 0);
}
use of com.github.ambry.rest.RestMethod in project ambry by linkedin.
the class AmbrySecurityService method processResponse.
@Override
public void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo, Callback<Void> callback) {
Exception exception = null;
frontendMetrics.securityServiceProcessResponseRate.mark();
long startTimeMs = System.currentTimeMillis();
if (!isOpen) {
exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable);
} else {
if (restRequest == null || responseChannel == null) {
throw new IllegalArgumentException("One of the required params is null");
}
RequestPath requestPath = RestUtils.getRequestPath(restRequest);
RestMethod restMethod = restRequest.getRestMethod();
if (blobInfo == null && !restMethod.equals(RestMethod.OPTIONS) && !restMethod.equals(RestMethod.PUT)) {
if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) {
throw new IllegalArgumentException("BlobInfo is null");
}
}
try {
GetBlobOptions options;
responseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime());
switch(restMethod) {
case HEAD:
options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, restRequest, NO_BLOB_SEGMENT_IDX_SPECIFIED);
responseChannel.setStatus(options.getRange() == null ? ResponseStatus.Ok : ResponseStatus.PartialContent);
responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs()));
setHeadResponseHeaders(blobInfo, options, restRequest, responseChannel);
break;
case GET:
if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) {
options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, restRequest, NO_BLOB_SEGMENT_IDX_SPECIFIED);
responseChannel.setStatus(ResponseStatus.Ok);
RestUtils.SubResource subResource = RestUtils.getRequestPath(restRequest).getSubResource();
responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs()));
if (subResource == null) {
Long ifModifiedSinceMs = getIfModifiedSinceMs(restRequest);
if (ifModifiedSinceMs != null && RestUtils.toSecondsPrecisionInMs(blobInfo.getBlobProperties().getCreationTimeInMs()) <= ifModifiedSinceMs) {
responseChannel.setStatus(ResponseStatus.NotModified);
} else {
if (options.getRange() != null) {
responseChannel.setStatus(ResponseStatus.PartialContent);
}
setGetBlobResponseHeaders(blobInfo, options, responseChannel);
setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel);
setAccountAndContainerHeaders(restRequest, responseChannel);
setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel);
responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion());
}
setCacheHeaders(restRequest, responseChannel);
} else {
if (subResource.equals(RestUtils.SubResource.BlobInfo)) {
setBlobInfoHeaders(blobInfo.getBlobProperties(), responseChannel);
setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel);
setAccountAndContainerHeaders(restRequest, responseChannel);
responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion());
} else if (subResource.equals(SubResource.Segment)) {
setGetBlobResponseHeaders(blobInfo, options, responseChannel);
setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel);
setAccountAndContainerHeaders(restRequest, responseChannel);
}
if (!setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel)) {
restRequest.setArg(InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY, true);
}
}
}
break;
case POST:
responseChannel.setStatus(ResponseStatus.Created);
responseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0);
responseChannel.setHeader(RestUtils.Headers.CREATION_TIME, new Date(blobInfo.getBlobProperties().getCreationTimeInMs()));
break;
case OPTIONS:
case PUT:
if (requestPath.matchesOperation(Operations.NAMED_BLOB)) {
responseChannel.setStatus(ResponseStatus.Created);
responseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0);
responseChannel.setHeader(RestUtils.Headers.CREATION_TIME, new Date(blobInfo.getBlobProperties().getCreationTimeInMs()));
}
break;
default:
exception = new RestServiceException("Cannot process response for request with method " + restMethod, RestServiceErrorCode.InternalServerError);
}
} catch (RestServiceException e) {
exception = e;
}
}
processRequestCharges(restRequest, responseChannel, blobInfo);
frontendMetrics.securityServiceProcessResponseTimeInMs.update(System.currentTimeMillis() - startTimeMs);
callback.onCompletion(null, exception);
}
use of com.github.ambry.rest.RestMethod 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.RestMethod 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);
}
Aggregations