use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class RouterStoreTest method testSizeLimitInList.
/**
* Test when the number of updates exceeds the maximum number of versions to save. RouterStore should start removing
* the old blobs.
*/
@Test
public void testSizeLimitInList() throws Exception {
RouterStore store = new RouterStore(accountServiceMetrics, backup, helixStore, new AtomicReference<>(router), forBackfill, TOTAL_NUMBER_OF_VERSION_TO_KEEP, config);
Map<Short, Account> idToRefAccountMap = new HashMap<>();
Map<Short, Map<Short, Container>> idtoRefContainerMap = new HashMap<>();
Set<Short> accountIDSet = new HashSet<>();
for (int i = 0; i < TOTAL_NUMBER_OF_VERSION_TO_KEEP; i++) {
// generate an new account and test update and fetch on this account
Map<Short, Account> newIdToRefAccountMap = new HashMap<>();
AccountTestUtils.generateRefAccounts(newIdToRefAccountMap, idtoRefContainerMap, accountIDSet, 1, 1);
if (!forBackfill) {
for (Map.Entry<Short, Account> entry : newIdToRefAccountMap.entrySet()) {
idToRefAccountMap.put(entry.getKey(), entry.getValue());
}
} else {
idToRefAccountMap = newIdToRefAccountMap;
}
assertUpdateAndFetch(store, idToRefAccountMap, newIdToRefAccountMap, i + 1, i + 1);
}
// Now we already have maximum number of versions in the list, adding a new version should remove the oldest one.
List<RouterStore.BlobIDAndVersion> blobIDAndVersions = getBlobIDAndVersionInHelix(TOTAL_NUMBER_OF_VERSION_TO_KEEP);
Collections.sort(blobIDAndVersions, Comparator.comparing(RouterStore.BlobIDAndVersion::getVersion));
assertEquals(1, blobIDAndVersions.get(0).getVersion());
Map<Short, Account> newIdToRefAccountMap = new HashMap<>();
AccountTestUtils.generateRefAccounts(newIdToRefAccountMap, idtoRefContainerMap, accountIDSet, 1, 1);
if (!forBackfill) {
for (Map.Entry<Short, Account> entry : newIdToRefAccountMap.entrySet()) {
idToRefAccountMap.put(entry.getKey(), entry.getValue());
}
} else {
idToRefAccountMap = newIdToRefAccountMap;
}
assertUpdateAndFetch(store, idToRefAccountMap, newIdToRefAccountMap, TOTAL_NUMBER_OF_VERSION_TO_KEEP + 1, TOTAL_NUMBER_OF_VERSION_TO_KEEP);
// Get the list again and compare the blob ids
List<RouterStore.BlobIDAndVersion> blobIDAndVersionsAfterUpdate = getBlobIDAndVersionInHelix(TOTAL_NUMBER_OF_VERSION_TO_KEEP);
Collections.sort(blobIDAndVersionsAfterUpdate, Comparator.comparing(RouterStore.BlobIDAndVersion::getVersion));
assertEquals("First version should be removed", 2, blobIDAndVersionsAfterUpdate.get(0).getVersion());
assertEquals("Version mismatch", TOTAL_NUMBER_OF_VERSION_TO_KEEP + 1, blobIDAndVersionsAfterUpdate.get(TOTAL_NUMBER_OF_VERSION_TO_KEEP - 1).getVersion());
for (int i = 1; i < TOTAL_NUMBER_OF_VERSION_TO_KEEP; i++) {
assertEquals("BlobIDAndVersion mismatch at index " + i, blobIDAndVersions.get(i), blobIDAndVersionsAfterUpdate.get(i - 1));
}
try {
router.getBlob(blobIDAndVersions.get(0).getBlobID(), new GetBlobOptionsBuilder().build()).get();
fail("Expecting not found exception");
} catch (ExecutionException e) {
Throwable t = e.getCause();
assertTrue("Cause should be RouterException", t instanceof RouterException);
assertEquals("ErrorCode mismatch", RouterErrorCode.BlobDoesNotExist, ((RouterException) t).getErrorCode());
}
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class MockHeadCallback method handleGet.
@Override
public void handleGet(RestRequest restRequest, RestResponseChannel restResponseChannel) {
if (shouldProceed(restRequest, restResponseChannel)) {
String blobId = getBlobId(restRequest);
MockGetCallback callback = new MockGetCallback(this, restRequest, restResponseChannel);
router.getBlob(blobId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.All).build(), callback, null);
}
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class FrontendRestRequestService method securityPostProcessRequestCallback.
/**
* Build a callback to use for {@link SecurityService#postProcessRequest}. This callback forwards request to the
* {@link Router} once ID conversion is completed. In the case of some sub-resources
* (e.g., {@link SubResource#Replicas}), the request is completed and not forwarded to the {@link Router}.
* @param convertedId the converted blob ID to use in router requests.
* @param restRequest the {@link RestRequest}.
* @param restResponseChannel the {@link RestResponseChannel}.
* @param getCallback the {@link GetCallback} to use if this is a {@link RestMethod#GET} request, or null for other
* request types.
* @param headCallback the {@link HeadCallback} to use if this is a {@link RestMethod#HEAD} request, or null for other
* request types.
* @param deleteCallback the {@link DeleteCallback} to use if this is a {@link RestMethod#DELETE} request, or null for
* other request types.
* @return the {@link Callback} to use.
*/
private Callback<Void> securityPostProcessRequestCallback(String convertedId, RestRequest restRequest, RestResponseChannel restResponseChannel, GetCallback getCallback, HeadCallback headCallback, DeleteCallback deleteCallback) {
Callback<ReadableStreamChannel> completionCallback = (result, exception) -> submitResponse(restRequest, restResponseChannel, result, exception);
RestMethod restMethod = restRequest.getRestMethod();
AsyncOperationTracker.Metrics metrics;
switch(restMethod) {
case GET:
metrics = frontendMetrics.getSecurityPostProcessRequestMetrics;
break;
case HEAD:
metrics = frontendMetrics.headSecurityPostProcessRequestMetrics;
break;
case DELETE:
metrics = frontendMetrics.deleteSecurityPostProcessRequestMetrics;
break;
default:
throw new IllegalStateException("Unrecognized RestMethod: " + restMethod);
}
return FrontendUtils.buildCallback(metrics, result -> {
ReadableStreamChannel response = null;
switch(restMethod) {
case GET:
SubResource subResource = getRequestPath(restRequest).getSubResource();
// inject encryption metrics if need be
if (BlobId.isEncrypted(convertedId)) {
RestRequestMetrics restRequestMetrics = getMetricsGroupForGet(frontendMetrics, subResource).getRestRequestMetrics(restRequest.isSslUsed(), true);
restRequest.getMetricsTracker().injectMetrics(restRequestMetrics);
}
if (subResource == null) {
getCallback.markStartTime();
router.getBlob(convertedId, getCallback.options, getCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, true));
} else {
switch(subResource) {
case BlobInfo:
case UserMetadata:
case Segment:
getCallback.markStartTime();
router.getBlob(convertedId, getCallback.options, getCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, true));
break;
case Replicas:
response = getReplicasHandler.getReplicas(convertedId, restResponseChannel);
break;
}
}
break;
case HEAD:
GetOption getOption = getGetOption(restRequest, frontendConfig.defaultRouterGetOption);
// inject encryption metrics if need be
if (BlobId.isEncrypted(convertedId)) {
RestRequestMetrics requestMetrics = frontendMetrics.headBlobMetricsGroup.getRestRequestMetrics(restRequest.isSslUsed(), true);
restRequest.getMetricsTracker().injectMetrics(requestMetrics);
}
headCallback.markStartTime();
router.getBlob(convertedId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.BlobInfo).getOption(getOption).restRequest(restRequest).build(), headCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, false));
break;
case DELETE:
deleteCallback.markStartTime();
router.deleteBlob(convertedId, getHeader(restRequest.getArgs(), Headers.SERVICE_ID, false), deleteCallback, QuotaUtils.buildQuotaChargeCallback(restRequest, quotaManager, false));
break;
default:
throw new IllegalStateException("Unrecognized RestMethod: " + restMethod);
}
if (response != null) {
completionCallback.onCompletion(response, null);
}
}, restRequest.getUri(), logger, completionCallback);
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class RouterServerTestFramework method startGetBlob.
/**
* Submit a getBlob operation.
* @param options the {@link GetOption} associated with the request.
* @param checkDeleted {@code true}, checks that the blob is deleted.
* @param opChain the {@link OperationChain} object that this operation is a part of.
*/
private void startGetBlob(GetOption options, final boolean checkDeleted, final OperationChain opChain) {
Callback<GetBlobResult> callback = new TestCallback<>(opChain, checkDeleted);
Future<GetBlobResult> future = router.getBlob(opChain.blobId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.All).getOption(options).build(), callback, quotaChargeCallback);
TestFuture<GetBlobResult> testFuture = new TestFuture<GetBlobResult>(future, genLabel("getBlob", checkDeleted), opChain) {
@Override
void check() throws Exception {
if (checkDeleted) {
checkDeleted();
} else {
GetBlobResult result = get();
checkBlobInfo(result.getBlobInfo(), opChain, getOperationName());
checkBlob(result.getBlobDataChannel(), opChain, getOperationName());
}
}
};
opChain.testFutures.add(testFuture);
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class RouterServerTestFramework method startGetBlobAuthorizationFailTest.
/**
* Submit a getBlob operation with incorrect accountId/ContainerId in blobId.
* @param opChain the {@link OperationChain} object that this operation is a part of.
*/
private void startGetBlobAuthorizationFailTest(final OperationChain opChain) {
Callback<GetBlobResult> callback = new TestCallback<>(opChain, true);
BlobId originalId, fraudId;
try {
originalId = new BlobId(opChain.blobId, clusterMap);
fraudId = BlobId.craft(originalId, originalId.getVersion(), (short) (originalId.getAccountId() + 1), (short) (originalId.getContainerId() + 1));
} catch (IOException e) {
// If there is a blobId creation failure, throw the exception and don't need to do actual action.
FutureResult<Void> future = new FutureResult<>();
// continue the chain
future.done(null, e);
callback.onCompletion(null, e);
TestFuture<Void> testFuture = new TestFuture<Void>(future, genLabel("getBlobAuthorizationFail", true), opChain) {
@Override
void check() throws Exception {
throw e;
}
};
opChain.testFutures.add(testFuture);
return;
}
// If everything good:
Future<GetBlobResult> future = router.getBlob(fraudId.getID(), new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.All).getOption(GetOption.Include_All).build(), callback, quotaChargeCallback);
TestFuture<GetBlobResult> testFuture = new TestFuture<GetBlobResult>(future, genLabel("getBlobAuthorizationFail", true), opChain) {
@Override
void check() throws Exception {
checkExpectedRouterErrorCode(RouterErrorCode.BlobAuthorizationFailure);
}
};
opChain.testFutures.add(testFuture);
}
Aggregations