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