Search in sources :

Example 1 with Container

use of com.github.ambry.account.Container in project ambry by linkedin.

the class AccountAndContainerInjector method injectAccountAndContainerUsingAccountAndContainerHeaders.

/**
 * Injects {@link Account} and {@link Container} for the PUT requests that carry the target account and container headers.
 * @param restRequest The {@link RestRequest} to inject {@link Account} and {@link Container} object.
 * @throws RestServiceException if either of {@link Account} or {@link Container} object could not be found.
 */
private void injectAccountAndContainerUsingAccountAndContainerHeaders(RestRequest restRequest) throws RestServiceException {
    String accountName = getHeader(restRequest.getArgs(), Headers.TARGET_ACCOUNT_NAME, false);
    Account targetAccount = accountService.getAccountByName(accountName);
    if (targetAccount == null) {
        frontendMetrics.unrecognizedAccountNameCount.inc();
        throw new RestServiceException("Account cannot be found for accountName=" + accountName + " in put request with account and container headers.", RestServiceErrorCode.InvalidAccount);
    }
    ensureAccountNameMatch(targetAccount, restRequest);
    String containerName = getHeader(restRequest.getArgs(), Headers.TARGET_CONTAINER_NAME, false);
    Container targetContainer = targetAccount.getContainerByName(containerName);
    if (targetContainer == null) {
        frontendMetrics.unrecognizedContainerNameCount.inc();
        throw new RestServiceException("Container cannot be found for accountName=" + accountName + " and containerName=" + containerName + " in put request with account and container headers.", RestServiceErrorCode.InvalidContainer);
    }
    setTargetAccountAndContainerInRestRequest(restRequest, targetAccount, targetContainer);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container)

Example 2 with Container

use of com.github.ambry.account.Container in project ambry by linkedin.

the class AccountAndContainerInjector method ensureAccountAndContainerInjected.

/**
 * If a non-unknown {@link Account} and {@link Container} was not previously injected, inject them into the provided
 * {@link RestRequest}, based on the given {@link BlobProperties}' service ID and blob privacy setting. This is useful
 * for V1 blob IDs that do not directly encode the account/container ID.
 * @param restRequest The {@link RestRequest} to inject {@link Account} and {@link Container}.
 * @param blobProperties The {@link BlobProperties} that contains the service id and blob privacy setting.
 * @throws RestServiceException if no valid account or container cound be identified for re-injection.
 */
public void ensureAccountAndContainerInjected(RestRequest restRequest, BlobProperties blobProperties) throws RestServiceException {
    Account targetAccount = (Account) restRequest.getArgs().get(RestUtils.InternalKeys.TARGET_ACCOUNT_KEY);
    Container targetContainer = (Container) restRequest.getArgs().get(RestUtils.InternalKeys.TARGET_CONTAINER_KEY);
    if (targetAccount == null || targetContainer == null) {
        throw new RestServiceException("Account and container were not injected by BlobStorageService", RestServiceErrorCode.InternalServerError);
    } else if (targetAccount.getId() == Account.UNKNOWN_ACCOUNT_ID) {
        // This should only occur for V1 blobs, where the blob ID does not contain the actual account and container IDs.
        String serviceId = blobProperties.getServiceId();
        boolean isPrivate = blobProperties.isPrivate();
        injectAccountAndContainerUsingServiceId(restRequest, serviceId, isPrivate);
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container)

Example 3 with Container

use of com.github.ambry.account.Container in project ambry by linkedin.

the class AccountAndContainerInjector method injectAccountAndContainerUsingServiceId.

/**
 * Inject {@link Account} and {@link Container} into a {@link RestRequest} based on a blob's service ID and
 * privacy setting.
 * @param restRequest The {@link RestRequest} to inject {@link Account} and {@link Container} object.
 * @param serviceId The service ID associated with the blob.
 * @param isPrivate The blob's privacy setting.
 * @throws RestServiceException if either of {@link Account} or {@link Container} object could not be found.
 */
private void injectAccountAndContainerUsingServiceId(RestRequest restRequest, String serviceId, boolean isPrivate) throws RestServiceException {
    // First, try to see if a migrated account exists for the service ID.
    Account targetAccount = accountService.getAccountByName(serviceId);
    if (targetAccount == null) {
        frontendMetrics.unrecognizedServiceIdCount.inc();
        logger.debug("Account cannot be found for put request with serviceId={}. Setting targetAccount to UNKNOWN_ACCOUNT", serviceId);
        // If a migrated account does not exist fall back to the UNKNOWN_ACCOUNT.
        targetAccount = accountService.getAccountById(Account.UNKNOWN_ACCOUNT_ID);
    }
    // Either the UNKNOWN_ACCOUNT, or the migrated account should contain default public/private containers
    Container targetContainer = targetAccount.getContainerById(isPrivate ? Container.DEFAULT_PRIVATE_CONTAINER_ID : Container.DEFAULT_PUBLIC_CONTAINER_ID);
    if (targetContainer == null) {
        throw new RestServiceException("Invalid account or container to inject; serviceId=" + serviceId + ", isPrivate=" + isPrivate, RestServiceErrorCode.InternalServerError);
    }
    setTargetAccountAndContainerInRestRequest(restRequest, targetAccount, targetContainer);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container)

Example 4 with Container

use of com.github.ambry.account.Container in project ambry by linkedin.

the class AccountAndContainerInjector method injectTargetAccountAndContainerFromBlobId.

/**
 * Obtains the target {@link Account} and {@link Container} id from the blobId string, queries the {@link AccountService}
 * to get the corresponding {@link Account} and {@link Container}, and injects the target {@link Account} and
 * {@link Container} into the {@link RestRequest}.
 * @param blobId The blobId to get the target {@link Account} and {@link Container} id.
 * @param restRequest The rest request to insert the target {@link Account} and {@link Container}.
 * @throws RestServiceException if 1) either {@link Account} or {@link Container} could not be found; or 2)
 *                              either {@link Account} or {@link Container} were explicitly specified as
 *                              {@link Account#UNKNOWN_ACCOUNT} or {@link Container#UNKNOWN_CONTAINER}.
 */
public void injectTargetAccountAndContainerFromBlobId(BlobId blobId, RestRequest restRequest) throws RestServiceException {
    Account targetAccount = accountService.getAccountById(blobId.getAccountId());
    if (targetAccount == null) {
        frontendMetrics.getHeadDeleteUnrecognizedAccountCount.inc();
        // @todo The check can be removed once HelixAccountService is running with UNKNOWN_ACCOUNT created.
        if (blobId.getAccountId() != Account.UNKNOWN_ACCOUNT_ID) {
            throw new RestServiceException("Account from blobId=" + blobId.getID() + "with accountId=" + blobId.getAccountId() + " cannot be recognized", RestServiceErrorCode.InvalidAccount);
        } else {
            logger.debug("Account cannot be found for blobId={} with accountId={}. Setting targetAccount to UNKNOWN_ACCOUNT", blobId.getID(), blobId.getAccountId());
            targetAccount = accountService.getAccountById(Account.UNKNOWN_ACCOUNT_ID);
        }
    }
    Container targetContainer = targetAccount.getContainerById(blobId.getContainerId());
    if (targetContainer == null) {
        frontendMetrics.getHeadDeleteUnrecognizedContainerCount.inc();
        throw new RestServiceException("Container from blobId=" + blobId.getID() + "with accountId=" + blobId.getAccountId() + " containerId=" + blobId.getContainerId() + " cannot be recognized", RestServiceErrorCode.InvalidContainer);
    }
    setTargetAccountAndContainerInRestRequest(restRequest, targetAccount, targetContainer);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container)

Example 5 with Container

use of com.github.ambry.account.Container in project ambry by linkedin.

the class FrontendIntegrationTest method multipartPostGetHeadTest.

/**
 * Tests multipart POST and verifies it via GET operations.
 * @throws Exception
 */
@Test
public void multipartPostGetHeadTest() throws Exception {
    Account refAccount = ACCOUNT_SERVICE.createAndAddRandomAccount();
    Container refContainer = refAccount.getContainerById(Container.DEFAULT_PUBLIC_CONTAINER_ID);
    doPostGetHeadDeleteTest(0, refAccount, refContainer, refAccount.getName(), !refContainer.isCacheable(), refAccount.getName(), refContainer.getName(), true);
    doPostGetHeadDeleteTest(FRONTEND_CONFIG.frontendChunkedGetResponseThresholdInBytes * 3, refAccount, refContainer, refAccount.getName(), !refContainer.isCacheable(), refAccount.getName(), refContainer.getName(), true);
    // failure case
    // size of content being POSTed is higher than what is allowed via multipart/form-data
    long maxAllowedSizeBytes = new NettyConfig(FRONTEND_VERIFIABLE_PROPS).nettyMultipartPostMaxSizeBytes;
    ByteBuffer content = ByteBuffer.wrap(TestUtils.getRandomBytes((int) maxAllowedSizeBytes + 1));
    HttpHeaders headers = new DefaultHttpHeaders();
    setAmbryHeadersForPut(headers, 7200, !refContainer.isCacheable(), refAccount.getName(), "application/octet-stream", null, refAccount.getName(), refContainer.getName());
    HttpRequest httpRequest = RestTestUtils.createRequest(HttpMethod.POST, "/", headers);
    HttpPostRequestEncoder encoder = createEncoder(httpRequest, content, ByteBuffer.allocate(0));
    ResponseParts responseParts = nettyClient.sendRequest(encoder.finalizeRequest(), encoder, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status());
    assertTrue("No Date header", response.headers().getTimeMillis(HttpHeaderNames.DATE, -1) != -1);
    assertFalse("Channel should not be active", HttpUtil.isKeepAlive(response));
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) Account(com.github.ambry.account.Account) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) Container(com.github.ambry.account.Container) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) HttpPostRequestEncoder(io.netty.handler.codec.http.multipart.HttpPostRequestEncoder) HttpResponse(io.netty.handler.codec.http.HttpResponse) ResponseParts(com.github.ambry.rest.NettyClient.ResponseParts) NettyConfig(com.github.ambry.config.NettyConfig) ByteBuffer(java.nio.ByteBuffer) UtilsTest(com.github.ambry.utils.UtilsTest) Test(org.junit.Test)

Aggregations

Container (com.github.ambry.account.Container)119 Account (com.github.ambry.account.Account)88 Test (org.junit.Test)61 ArrayList (java.util.ArrayList)30 RestServiceException (com.github.ambry.rest.RestServiceException)20 ContainerBuilder (com.github.ambry.account.ContainerBuilder)17 JSONObject (org.json.JSONObject)17 VerifiableProperties (com.github.ambry.config.VerifiableProperties)16 HashSet (java.util.HashSet)15 HashMap (java.util.HashMap)14 Properties (java.util.Properties)14 AccountBuilder (com.github.ambry.account.AccountBuilder)13 RestRequest (com.github.ambry.rest.RestRequest)13 ByteBuffer (java.nio.ByteBuffer)13 Map (java.util.Map)13 MetricRegistry (com.codahale.metrics.MetricRegistry)12 TestUtils (com.github.ambry.utils.TestUtils)12 Collections (java.util.Collections)12 List (java.util.List)12 Assert (org.junit.Assert)12