Search in sources :

Example 31 with RestServiceException

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

the class AmbryBlobStorageService method handlePut.

@Override
public void handlePut(RestRequest restRequest, RestResponseChannel restResponseChannel) {
    handlePrechecks(restRequest, restResponseChannel);
    Exception exception = isUp ? new RestServiceException("PUT is not supported", RestServiceErrorCode.UnsupportedHttpMethod) : new RestServiceException("AmbryBlobStorageService unavailable", RestServiceErrorCode.ServiceUnavailable);
    submitResponse(restRequest, restResponseChannel, null, exception);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) IOException(java.io.IOException) RouterException(com.github.ambry.router.RouterException) ExecutionException(java.util.concurrent.ExecutionException) RestServiceException(com.github.ambry.rest.RestServiceException)

Example 32 with RestServiceException

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

the class AmbrySecurityService method postProcessRequest.

@Override
public void postProcessRequest(RestRequest restRequest, Callback<Void> callback) {
    Exception exception = null;
    frontendMetrics.securityServicePostProcessRequestRate.mark();
    long startTimeMs = System.currentTimeMillis();
    if (!isOpen) {
        exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable);
    } else if (restRequest == null || callback == null) {
        throw new IllegalArgumentException("RestRequest or Callback is null");
    }
    // check preconditions for DELETE request
    if (restRequest.getRestMethod() == RestMethod.DELETE) {
        try {
            accountAndContainerNamePreconditionCheck(restRequest);
        } catch (Exception e) {
            exception = e;
        }
    }
    frontendMetrics.securityServicePostProcessRequestTimeInMs.update(System.currentTimeMillis() - startTimeMs);
    callback.onCompletion(null, exception);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) RestServiceException(com.github.ambry.rest.RestServiceException)

Example 33 with RestServiceException

use of com.github.ambry.rest.RestServiceException 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");
        }
        String operationOrBlobId = RestUtils.getOperationOrBlobIdFromUri(restRequest, RestUtils.getBlobSubResource(restRequest), frontendConfig.frontendPathPrefixesToRemove);
        if (operationOrBlobId.startsWith("/")) {
            operationOrBlobId = operationOrBlobId.substring(1);
        }
        if (blobInfo == null && !restRequest.getRestMethod().equals(RestMethod.OPTIONS)) {
            if (!operationOrBlobId.equals(Operations.GET_SIGNED_URL)) {
                throw new IllegalArgumentException("BlobInfo is null");
            }
        }
        try {
            GetBlobOptions options;
            responseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime());
            RestMethod restMethod = restRequest.getRestMethod();
            switch(restMethod) {
                case HEAD:
                    options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None);
                    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 (!operationOrBlobId.equals(Operations.GET_SIGNED_URL)) {
                        responseChannel.setStatus(ResponseStatus.Ok);
                        RestUtils.SubResource subResource = RestUtils.getBlobSubResource(restRequest);
                        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 {
                                options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None);
                                if (options.getRange() != null) {
                                    responseChannel.setStatus(ResponseStatus.PartialContent);
                                }
                                setGetBlobResponseHeaders(blobInfo, options, responseChannel);
                            }
                            setCacheHeaders(restRequest, responseChannel);
                        } else {
                            if (subResource.equals(RestUtils.SubResource.BlobInfo)) {
                                setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel);
                                setAccountAndContainerHeaders(restRequest, responseChannel);
                            }
                        }
                    }
                    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:
                    break;
                default:
                    exception = new RestServiceException("Cannot process response for request with method " + restMethod, RestServiceErrorCode.InternalServerError);
            }
        } catch (RestServiceException e) {
            exception = e;
        }
    }
    frontendMetrics.securityServiceProcessResponseTimeInMs.update(System.currentTimeMillis() - startTimeMs);
    callback.onCompletion(null, exception);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) GetBlobOptions(com.github.ambry.router.GetBlobOptions) GregorianCalendar(java.util.GregorianCalendar) RestUtils(com.github.ambry.rest.RestUtils) RestServiceException(com.github.ambry.rest.RestServiceException) Date(java.util.Date) RestMethod(com.github.ambry.rest.RestMethod)

Example 34 with RestServiceException

use of com.github.ambry.rest.RestServiceException 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());
    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
    try {
        doOperation(createRestRequest(RestMethod.GET, Operations.GET_SIGNED_URL, null, null), new MockRestResponseChannel());
        fail("Operation should have failed because some necessary parameters are missing");
    } catch (RestServiceException e) {
        assertEquals("RestServiceErrorCode not as expected", RestServiceErrorCode.MissingArgs, e.getErrorCode());
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) 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) RestUtilsTest(com.github.ambry.rest.RestUtilsTest) UtilsTest(com.github.ambry.utils.UtilsTest) Test(org.junit.Test)

Example 35 with RestServiceException

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

the class FrontendTestUrlSigningServiceFactory method doConditionalDeleteTest.

/**
 * Tests blob conditional DELETE operations on the given {@code container}.
 * @param toPostAccount the {@link Account} to use in post headers. Can be {@code null} if only using service ID.
 * @param toPostContainer the {@link Container} to use in post headers. Can be {@code null} if only using service ID.
 * @param serviceId the serviceId to use for the POST
 * @param isPrivate the isPrivate flag to pass as part of the POST
 * @param expectedAccount the {@link Account} details that are eventually expected to be populated.
 * @param expectedContainer the {@link Container} details that are eventually expected to be populated.
 * @throws Exception
 */
private void doConditionalDeleteTest(Account toPostAccount, Container toPostContainer, String serviceId, boolean isPrivate, Account expectedAccount, Container expectedContainer) throws Exception {
    final int CONTENT_LENGTH = 1024;
    ByteBuffer content = ByteBuffer.wrap(TestUtils.getRandomBytes(CONTENT_LENGTH));
    String contentType = "application/octet-stream";
    String ownerId = "postGetHeadDeleteOwnerID";
    JSONObject headers = new JSONObject();
    String accountNameInPost = toPostAccount != null ? toPostAccount.getName() : null;
    String containerNameInPost = toPostContainer != null ? toPostContainer.getName() : null;
    setAmbryHeadersForPut(headers, 7200, isPrivate, serviceId, contentType, ownerId, accountNameInPost, containerNameInPost);
    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);
    // perform POST, GET, HEAD successfully before DELETE
    String blobId = postBlobAndVerify(headers, content, expectedAccount, expectedContainer);
    headers.put(RestUtils.Headers.BLOB_SIZE, (long) CONTENT_LENGTH);
    getBlobAndVerify(blobId, null, null, headers, content, expectedAccount, expectedContainer);
    getHeadAndVerify(blobId, null, null, headers, expectedAccount, expectedContainer);
    // test Conditional Delete failure because only container name is set
    RestResponseChannel restResponseChannel = new MockRestResponseChannel();
    JSONObject headers2 = new JSONObject();
    setAccountAndContainerHeaders(headers2, null, containerNameInPost);
    RestRequest restRequest = createRestRequest(RestMethod.DELETE, blobId, headers2, null);
    try {
        doOperation(restRequest, restResponseChannel);
        fail("Operation should have failed because only container name is set");
    } catch (RestServiceException e) {
        assertEquals("AmbryBlobStorageService should have thrown a BadRequest exception", RestServiceErrorCode.BadRequest, e.getErrorCode());
    }
    // test Conditional Delete failure because of incorrect account name
    restResponseChannel = new MockRestResponseChannel();
    setAccountAndContainerHeaders(headers, "INCORRECT_ACCOUNT_NAME", containerNameInPost);
    restRequest = createRestRequest(RestMethod.DELETE, blobId, headers, null);
    try {
        doOperation(restRequest, restResponseChannel);
        fail("Operation should have failed because incorrect account name");
    } catch (RestServiceException e) {
        assertEquals("AmbryBlobStorageService should have thrown a PreconditionFailed exception", RestServiceErrorCode.PreconditionFailed, e.getErrorCode());
    }
    // test Conditional Delete failure because of incorrect container name
    restResponseChannel = new MockRestResponseChannel();
    setAccountAndContainerHeaders(headers, accountNameInPost, "INCORRECT_CONTAINER_NAME");
    restRequest = createRestRequest(RestMethod.DELETE, blobId, headers, null);
    try {
        doOperation(restRequest, restResponseChannel);
        fail("Operation should have failed because incorrect container name");
    } catch (RestServiceException e) {
        assertEquals("AmbryBlobStorageService should have thrown a PreconditionFailed exception", RestServiceErrorCode.PreconditionFailed, e.getErrorCode());
    }
    // test Conditional Delete succeeds
    setAccountAndContainerHeaders(headers, accountNameInPost, containerNameInPost);
    restRequest = createRestRequest(RestMethod.DELETE, blobId, headers, null);
    verifyDeleteAccepted(restRequest);
    // check GET, HEAD and DELETE after delete.
    verifyOperationsAfterDelete(blobId, headers, content, expectedAccount, expectedContainer);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) HashMap(java.util.HashMap) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) ByteBuffer(java.nio.ByteBuffer)

Aggregations

RestServiceException (com.github.ambry.rest.RestServiceException)35 MockRestResponseChannel (com.github.ambry.rest.MockRestResponseChannel)15 Test (org.junit.Test)12 MockRestRequest (com.github.ambry.rest.MockRestRequest)11 RestRequest (com.github.ambry.rest.RestRequest)10 UtilsTest (com.github.ambry.utils.UtilsTest)8 JSONObject (org.json.JSONObject)8 RestMethod (com.github.ambry.rest.RestMethod)7 RestUtilsTest (com.github.ambry.rest.RestUtilsTest)6 Account (com.github.ambry.account.Account)5 Container (com.github.ambry.account.Container)5 IOException (java.io.IOException)4 ByteBuffer (java.nio.ByteBuffer)4 ExecutionException (java.util.concurrent.ExecutionException)4 BlobId (com.github.ambry.commons.BlobId)3 RestUtils (com.github.ambry.rest.RestUtils)3 MetricRegistry (com.codahale.metrics.MetricRegistry)2 PartitionId (com.github.ambry.clustermap.PartitionId)2 VerifiableProperties (com.github.ambry.config.VerifiableProperties)2 RestResponseChannel (com.github.ambry.rest.RestResponseChannel)2