use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class RestUtils method buildGetBlobOptions.
/**
* Build a {@link GetBlobOptions} object from an argument map for a certain sub-resource.
* @param args the arguments associated with the request. This is typically a map of header names and query string
* arguments to values.
* @param subResource the {@link SubResource} for the request, or {@code null} if no sub-resource is requested.
* @param getOption the {@link GetOption} required.
* @param restRequest the {@link RestRequest} that initiate this get operation, null if no rest request is available.
* @param blobSegmentIdx index of blob segment one wishes to GET, {@link GetBlobOptions#NO_BLOB_SEGMENT_IDX_SPECIFIED}
* if not used
* @return a populated {@link GetBlobOptions} object.
* @throws RestServiceException if the {@link GetBlobOptions} could not be constructed.
*/
public static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource, GetOption getOption, RestRequest restRequest, int blobSegmentIdx) throws RestServiceException {
String rangeHeaderValue = getHeader(args, Headers.RANGE, false);
if (subResource != null && !subResource.equals(SubResource.Segment) && rangeHeaderValue != null) {
throw new RestServiceException("Ranges not supported for sub-resources that aren't Segment.", RestServiceErrorCode.InvalidArgs);
}
boolean resolveRangeOnEmptyBlob = getBooleanHeader(args, Headers.RESOLVE_RANGE_ON_EMPTY_BLOB, false);
return new GetBlobOptionsBuilder().operationType(subResource == null || subResource == SubResource.Segment ? GetBlobOptions.OperationType.All : GetBlobOptions.OperationType.BlobInfo).getOption(getOption).blobSegment(blobSegmentIdx).range(rangeHeaderValue != null ? RestUtils.buildByteRange(rangeHeaderValue) : null).resolveRangeOnEmptyBlob(resolveRangeOnEmptyBlob).restRequest(restRequest).build();
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class UndeleteHandlerTest method verifyUndelete.
/**
* Verifies that the blob is undeleted
* @param restRequest the {@link RestRequest} to get a signed URL.
* @param expectedAccount the {@link Account} that should be populated in {@link RestRequest}.
* @param expectedContainer the {@link Container} that should be populated in {@link RestRequest}.
* @throws Exception
*/
private void verifyUndelete(RestRequest restRequest, Account expectedAccount, Container expectedContainer) throws Exception {
try {
router.getBlob(blobId, new GetBlobOptionsBuilder().build()).get(1, TimeUnit.SECONDS);
fail("Get blob should fail on a deleted blob");
} catch (ExecutionException e) {
RouterException routerException = (RouterException) e.getCause();
assertEquals(RouterErrorCode.BlobDeleted, routerException.getErrorCode());
}
RestResponseChannel restResponseChannel = new MockRestResponseChannel();
sendRequestGetResponse(restRequest, restResponseChannel);
assertEquals("ResponseStatus not as expected", ResponseStatus.Ok, restResponseChannel.getStatus());
assertNotNull("Date has not been set", restResponseChannel.getHeader(RestUtils.Headers.DATE));
assertEquals("Content-length is not as expected", 0, Integer.parseInt((String) restResponseChannel.getHeader(RestUtils.Headers.CONTENT_LENGTH)));
assertEquals("Account not as expected", expectedAccount, restRequest.getArgs().get(RestUtils.InternalKeys.TARGET_ACCOUNT_KEY));
assertEquals("Container not as expected", expectedContainer, restRequest.getArgs().get(RestUtils.InternalKeys.TARGET_CONTAINER_KEY));
router.getBlob(blobId, new GetBlobOptionsBuilder().build()).get(1, TimeUnit.SECONDS);
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class MockHeadCallback method handleHead.
@Override
public void handleHead(RestRequest restRequest, RestResponseChannel restResponseChannel) {
if (shouldProceed(restRequest, restResponseChannel)) {
String blobId = getBlobId(restRequest);
router.getBlob(blobId, new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.BlobInfo).build(), new MockHeadCallback(this, restRequest, restResponseChannel), null);
}
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class TtlUpdateHandlerTest method assertTtl.
/**
* Verifies that the TTL is {@code expectedTtlSecs}
* @param expectedTtlSecs the expected TTL (in secs) of the blob
* @throws Exception
*/
private void assertTtl(long expectedTtlSecs) throws Exception {
GetBlobResult result = router.getBlob(blobId, new GetBlobOptionsBuilder().build()).get(1, TimeUnit.SECONDS);
assertEquals("TTL not as expected", expectedTtlSecs, result.getBlobInfo().getBlobProperties().getTimeToLiveInSeconds());
}
use of com.github.ambry.router.GetBlobOptionsBuilder in project ambry by linkedin.
the class RouterStore method readAccountMetadataFromBlobID.
/**
* Fetch the {@link Account} metadata from the given blob id.
* @param blobID The blobID to fetch {@link Account} metadata from.
* @return {@link Account} metadata in a map, and null when there is any error.
*/
Map<String, String> readAccountMetadataFromBlobID(String blobID) {
long startTimeMs = System.currentTimeMillis();
Future<GetBlobResult> resultF = router.get().getBlob(blobID, new GetBlobOptionsBuilder().build());
try {
GetBlobResult result = resultF.get();
accountServiceMetrics.accountFetchFromAmbryTimeInMs.update(System.currentTimeMillis() - startTimeMs);
int blobSize = (int) result.getBlobInfo().getBlobProperties().getBlobSize();
InputStream input = new ReadableStreamChannelInputStream(result.getBlobDataChannel());
byte[] bytes = Utils.readBytesFromStream(input, blobSize);
JSONObject object = new JSONObject(new String(bytes, Charsets.UTF_8));
Map<String, String> map = new HashMap<>();
object.keySet().forEach(key -> map.put(key, object.getString(key)));
return map;
} catch (Exception e) {
logger.error("Failed to read account metadata from blob id={}", blobID, e);
accountServiceMetrics.accountFetchFromAmbryServerErrorCount.inc();
}
return null;
}
Aggregations