use of com.github.ambry.account.Account in project ambry by linkedin.
the class FrontendTestUrlSigningServiceFactory method validateSecurePathTest.
/**
* Test that the secure path is validated if required by {@link Container}.
* @throws Exception
*/
@Test
public void validateSecurePathTest() throws Exception {
short refAccountId = Utils.getRandomShort(TestUtils.RANDOM);
String refAccountName = TestUtils.getRandomString(10);
short[] refContainerIds = new short[] { 2, 3 };
String[] refContainerNames = new String[] { "SecurePathValidation", "NoValidation" };
Container signedPathRequiredContainer = new ContainerBuilder(refContainerIds[0], refContainerNames[0], Container.ContainerStatus.ACTIVE, "validate secure path", refAccountId).setSecurePathRequired(true).build();
Container noValidationContainer = new ContainerBuilder(refContainerIds[1], refContainerNames[1], Container.ContainerStatus.ACTIVE, "no validation on secure path", refAccountId).setSecurePathRequired(false).build();
Account account = new AccountBuilder(refAccountId, refAccountName, Account.AccountStatus.ACTIVE).addOrUpdateContainer(signedPathRequiredContainer).addOrUpdateContainer(noValidationContainer).build();
accountService.updateAccounts(Collections.singletonList(account));
ByteBuffer content = ByteBuffer.wrap(TestUtils.getRandomBytes(CONTENT_LENGTH));
String contentType = "application/octet-stream";
String ownerId = "SecurePathValidationTest";
JSONObject headers = new JSONObject();
setAmbryHeadersForPut(headers, TTL_SECS, false, refAccountName, contentType, ownerId, refAccountName, refContainerNames[0], null);
Map<String, String> userMetadata = new HashMap<>();
userMetadata.put(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key1", "value1");
RestUtilsTest.setUserMetadataHeaders(headers, userMetadata);
String blobId = postBlobAndVerify(headers, content, account, signedPathRequiredContainer);
headers.put(RestUtils.Headers.BLOB_SIZE, (long) CONTENT_LENGTH);
// test that secure path validation succeeded
String testUri = "/" + frontendConfig.securePathPrefix + blobId;
getBlobAndVerify(testUri, null, null, headers, content, account, signedPathRequiredContainer);
// test that no secure path should fail (return AccessDenied)
try {
getBlobAndVerify(blobId, null, null, headers, content, account, signedPathRequiredContainer);
fail("get blob should fail because secure path is missing");
} catch (RestServiceException e) {
assertEquals("Mismatch in error code", RestServiceErrorCode.AccessDenied, e.getErrorCode());
}
// test that secure path equals other prefix should fail (return AccessDenied)
try {
getBlobAndVerify("/media" + blobId, null, null, headers, content, account, signedPathRequiredContainer);
fail("get blob should fail because secure path equals other prefix and doesn't match expected one");
} catch (RestServiceException e) {
assertEquals("Mismatch in error code", RestServiceErrorCode.AccessDenied, e.getErrorCode());
}
// test that incorrect path should fail (return BadRequest)
try {
getBlobAndVerify("/incorrect-path" + blobId, null, null, headers, content, account, signedPathRequiredContainer);
fail("get blob should fail because secure path is incorrect");
} catch (RestServiceException e) {
assertEquals("Mismatch in error code", RestServiceErrorCode.BadRequest, e.getErrorCode());
}
// test container with no validation
setAmbryHeadersForPut(headers, TTL_SECS, false, refAccountName, contentType, ownerId, refAccountName, refContainerNames[1], null);
content = ByteBuffer.wrap(TestUtils.getRandomBytes(CONTENT_LENGTH));
blobId = postBlobAndVerify(headers, content, account, noValidationContainer);
// test container with no validation should fail if there is invalid path in URI
try {
getBlobAndVerify("/incorrect-path" + blobId, null, null, headers, content, account, noValidationContainer);
fail("get blob should fail because there is invalid path in uri");
} catch (RestServiceException e) {
assertEquals("Mismatch in error code", RestServiceErrorCode.BadRequest, e.getErrorCode());
}
// test container with no validation should succeed if URI is correct
getBlobAndVerify(blobId, null, null, headers, content, account, noValidationContainer);
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class FrontendTestUrlSigningServiceFactory method getAccountsTest.
/**
* Tests the handling of {@link Operations#ACCOUNTS} get requests.
* @throws Exception
*/
@Test
public void getAccountsTest() throws Exception {
RestRequest restRequest = createRestRequest(RestMethod.GET, Operations.ACCOUNTS, null, null);
MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
doOperation(restRequest, restResponseChannel);
Set<Account> expected = new HashSet<>(accountService.getAllAccounts());
Set<Account> actual = new HashSet<>(AccountCollectionSerde.accountsFromInputStreamInJson(new ByteArrayInputStream(restResponseChannel.getResponseBody())));
assertEquals("Unexpected GET /accounts response", expected, actual);
// test an account not found case to ensure that it goes through the exception path
restRequest = createRestRequest(RestMethod.GET, Operations.ACCOUNTS, new JSONObject().put(RestUtils.Headers.TARGET_ACCOUNT_ID, accountService.generateRandomAccount().getId()), null);
try {
doOperation(restRequest, new MockRestResponseChannel());
fail("Operation should have failed");
} catch (RestServiceException e) {
assertEquals("Error code not as expected", RestServiceErrorCode.NotFound, e.getErrorCode());
}
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class GetAccountsHandlerTest method getSingleContainerSuccessTest.
/**
* Test success case of getting single container.
* @throws Exception
*/
@Test
public void getSingleContainerSuccessTest() throws Exception {
Account existingAccount = accountService.createAndAddRandomAccount();
Container existingContainer = existingAccount.getAllContainers().iterator().next();
ThrowingBiConsumer<RestRequest, Container> testAction = (request, expectedContainer) -> {
RestResponseChannel restResponseChannel = new MockRestResponseChannel();
ReadableStreamChannel channel = sendRequestGetResponse(request, restResponseChannel);
assertNotNull("There should be a response", channel);
Assert.assertNotNull("Date has not been set", restResponseChannel.getHeader(RestUtils.Headers.DATE));
assertEquals("Content-type is not as expected", RestUtils.JSON_CONTENT_TYPE, restResponseChannel.getHeader(RestUtils.Headers.CONTENT_TYPE));
assertEquals("Content-length is not as expected", channel.getSize(), Integer.parseInt((String) restResponseChannel.getHeader(RestUtils.Headers.CONTENT_LENGTH)));
RetainingAsyncWritableChannel asyncWritableChannel = new RetainingAsyncWritableChannel((int) channel.getSize());
channel.readInto(asyncWritableChannel, null).get();
assertEquals("Container does not match", Collections.singletonList(expectedContainer), AccountCollectionSerde.containersFromInputStreamInJson(asyncWritableChannel.consumeContentAsInputStream(), existingAccount.getId()));
};
testAction.accept(createRestRequest(existingAccount.getName(), null, existingContainer.getName(), Operations.ACCOUNTS_CONTAINERS), existingContainer);
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class MySqlNamedBlobDbIntegrationTest method testPutGetListDeleteSequence.
/**
* Tests sequences of puts, gets, lists, and deletes across multiple containers.
* @throws Exception
*/
@Test
public void testPutGetListDeleteSequence() throws Exception {
int blobsPerContainer = 5;
List<NamedBlobRecord> records = new ArrayList<>();
for (Account account : accountService.getAllAccounts()) {
for (Container container : account.getAllContainers()) {
for (int i = 0; i < blobsPerContainer; i++) {
String blobId = getBlobId(account, container);
String blobName = "name/" + i + "/more path segments--";
long expirationTime = i % 2 == 0 ? Utils.Infinite_Time : System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1);
NamedBlobRecord record = new NamedBlobRecord(account.getName(), container.getName(), blobName, blobId, expirationTime);
namedBlobDb.put(record).get();
records.add(record);
}
}
}
// get records just inserted
for (NamedBlobRecord record : records) {
NamedBlobRecord recordFromStore = namedBlobDb.get(record.getAccountName(), record.getContainerName(), record.getBlobName()).get();
assertEquals("Record does not match expectations.", record, recordFromStore);
}
// list records in each container
for (Account account : accountService.getAllAccounts()) {
for (Container container : account.getAllContainers()) {
Page<NamedBlobRecord> page = namedBlobDb.list(account.getName(), container.getName(), "name", null).get();
assertNull("No continuation token expected", page.getNextPageToken());
assertEquals("Unexpected number of blobs in container", blobsPerContainer, page.getEntries().size());
}
}
// check that puts to the same keys fail.
for (Account account : accountService.getAllAccounts()) {
for (Container container : account.getAllContainers()) {
for (int i = 0; i < blobsPerContainer; i++) {
String blobId = getBlobId(account, container);
String blobName = "name/" + i + "/more path segments--";
NamedBlobRecord record = new NamedBlobRecord(account.getName(), container.getName(), blobName, blobId, Utils.Infinite_Time);
checkErrorCode(() -> namedBlobDb.put(record), RestServiceErrorCode.Conflict);
}
}
}
// delete the records and check that they cannot be fetched with a get call.
for (NamedBlobRecord record : records) {
DeleteResult deleteResult = namedBlobDb.delete(record.getAccountName(), record.getContainerName(), record.getBlobName()).get();
assertEquals("Unexpected deleted ID", record.getBlobId(), deleteResult.getBlobId());
assertFalse("Unexpected alreadyDeleted value", deleteResult.isAlreadyDeleted());
checkErrorCode(() -> namedBlobDb.get(record.getAccountName(), record.getContainerName(), record.getBlobName()), RestServiceErrorCode.Deleted);
}
// deletes should be idempotent and additional delete calls should succeed
for (NamedBlobRecord record : records) {
DeleteResult deleteResult = namedBlobDb.delete(record.getAccountName(), record.getContainerName(), record.getBlobName()).get();
assertEquals("Unexpected deleted ID", record.getBlobId(), deleteResult.getBlobId());
assertTrue("Unexpected alreadyDeleted value", deleteResult.isAlreadyDeleted());
}
// delete and get for non existent blobs should return not found.
for (NamedBlobRecord record : records) {
String nonExistentName = record.getBlobName() + "-other";
checkErrorCode(() -> namedBlobDb.get(record.getAccountName(), record.getContainerName(), nonExistentName), RestServiceErrorCode.NotFound);
checkErrorCode(() -> namedBlobDb.delete(record.getAccountName(), record.getContainerName(), nonExistentName), RestServiceErrorCode.NotFound);
}
records.clear();
// should be able to put new records again after deletion
for (Account account : accountService.getAllAccounts()) {
for (Container container : account.getAllContainers()) {
for (int i = 0; i < blobsPerContainer; i++) {
String blobId = getBlobId(account, container);
String blobName = "name/" + i + "/more path segments--";
long expirationTime = i % 2 == 1 ? Utils.Infinite_Time : System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1);
NamedBlobRecord record = new NamedBlobRecord(account.getName(), container.getName(), blobName, blobId, expirationTime);
namedBlobDb.put(record).get();
records.add(record);
}
}
}
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class AmbryCUQuotaSourceTest method testChargeForValidResource.
@Test
public void testChargeForValidResource() throws Exception {
Account account = inMemAccountService.getAccountById((short) 102);
Container container = new ArrayList<>(account.getAllContainers()).get(0);
ambryCUQuotaSource.chargeUsage(QuotaResource.fromContainer(container), QuotaName.READ_CAPACITY_UNIT, 102400000);
Assert.assertEquals(10.0, ambryCUQuotaSource.getUsage(QuotaResource.fromContainer(container), QuotaName.READ_CAPACITY_UNIT), 0.01);
Assert.assertEquals(0, ambryCUQuotaSource.getUsage(QuotaResource.fromContainer(container), QuotaName.WRITE_CAPACITY_UNIT), 0.01);
ambryCUQuotaSource.chargeUsage(QuotaResource.fromContainer(container), QuotaName.WRITE_CAPACITY_UNIT, 102400000);
Assert.assertEquals(10.0, ambryCUQuotaSource.getUsage(QuotaResource.fromContainer(container), QuotaName.READ_CAPACITY_UNIT), 0.01);
Assert.assertEquals(10.0, ambryCUQuotaSource.getUsage(QuotaResource.fromContainer(container), QuotaName.WRITE_CAPACITY_UNIT), 0.01);
}
Aggregations