use of com.github.ambry.router.FutureResult in project ambry by linkedin.
the class NamedBlobPutHandlerTest method stitchBlobAndVerify.
/**
* Make a stitch blob call using {@link PostBlobHandler} and verify the result of the operation.
* @param requestBody the body of the stitch request to supply.
* @param expectedStitchedChunks the expected chunks stitched together.
* @param errorChecker if non-null, expect an exception to be thrown by the post flow and verify it using this
* {@link ThrowingConsumer}.
* @throws Exception
*/
private void stitchBlobAndVerify(byte[] requestBody, List<ChunkInfo> expectedStitchedChunks, ThrowingConsumer<ExecutionException> errorChecker) throws Exception {
// call
for (long ttl : new long[] { TestUtils.TTL_SECS, Utils.Infinite_Time }) {
JSONObject headers = new JSONObject();
FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, ttl, !REF_CONTAINER.isCacheable(), SERVICE_ID, CONTENT_TYPE, OWNER_ID, null, null, "STITCH");
RestRequest request = getRestRequest(headers, request_path, requestBody);
RestResponseChannel restResponseChannel = new MockRestResponseChannel();
FutureResult<Void> future = new FutureResult<>();
idConverterFactory.lastInput = null;
idConverterFactory.lastBlobInfo = null;
idConverterFactory.lastConvertedId = null;
namedBlobPutHandler.handle(request, restResponseChannel, future::done);
if (errorChecker == null) {
future.get(TIMEOUT_SECS, TimeUnit.SECONDS);
assertEquals("Unexpected location header", idConverterFactory.lastConvertedId, restResponseChannel.getHeader(RestUtils.Headers.LOCATION));
InMemoryRouter.InMemoryBlob blob = router.getActiveBlobs().get(idConverterFactory.lastInput);
assertEquals("List of chunks stitched does not match expected", expectedStitchedChunks, blob.getStitchedChunks());
ByteArrayOutputStream expectedContent = new ByteArrayOutputStream();
expectedStitchedChunks.stream().map(chunkInfo -> router.getActiveBlobs().get(chunkInfo.getBlobId()).getBlob().array()).forEach(buf -> expectedContent.write(buf, 0, buf.length));
assertEquals("Unexpected blob content stored", ByteBuffer.wrap(expectedContent.toByteArray()), blob.getBlob());
// check actual size of stitched blob
assertEquals("Unexpected blob size", Long.toString(getStitchedBlobSize(expectedStitchedChunks)), restResponseChannel.getHeader(RestUtils.Headers.BLOB_SIZE));
assertEquals("Unexpected TTL in named blob DB", ttl, idConverterFactory.lastBlobInfo.getBlobProperties().getTimeToLiveInSeconds());
assertEquals("Unexpected TTL in blob", ttl, blob.getBlobProperties().getTimeToLiveInSeconds());
} else {
TestUtils.assertException(ExecutionException.class, () -> future.get(TIMEOUT_SECS, TimeUnit.SECONDS), errorChecker);
}
}
}
use of com.github.ambry.router.FutureResult in project ambry by linkedin.
the class NamedBlobPutHandlerTest method putBlobAndVerify.
/**
* Make a stitch blob call using {@link PostBlobHandler} and verify the result of the operation.
* @param errorChecker if non-null, expect an exception to be thrown by the post flow and verify it using this
* {@link ThrowingConsumer}.
* @param ttl the ttl used for the blob
* @throws Exception
*/
private void putBlobAndVerify(ThrowingConsumer<ExecutionException> errorChecker, long ttl) throws Exception {
JSONObject headers = new JSONObject();
FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, ttl, !REF_CONTAINER.isCacheable(), SERVICE_ID, CONTENT_TYPE, OWNER_ID, null, null, null);
byte[] content = TestUtils.getRandomBytes(1024);
RestRequest request = getRestRequest(headers, request_path, content);
RestResponseChannel restResponseChannel = new MockRestResponseChannel();
FutureResult<Void> future = new FutureResult<>();
idConverterFactory.lastInput = null;
idConverterFactory.lastBlobInfo = null;
idConverterFactory.lastConvertedId = null;
namedBlobPutHandler.handle(request, restResponseChannel, future::done);
if (errorChecker == null) {
future.get(TIMEOUT_SECS, TimeUnit.SECONDS);
assertEquals("Unexpected location header", idConverterFactory.lastConvertedId, restResponseChannel.getHeader(RestUtils.Headers.LOCATION));
InMemoryRouter.InMemoryBlob blob = router.getActiveBlobs().get(idConverterFactory.lastInput);
assertEquals("Unexpected blob content stored", ByteBuffer.wrap(content), blob.getBlob());
assertEquals("Unexpected TTL in blob", ttl, blob.getBlobProperties().getTimeToLiveInSeconds());
assertEquals("Unexpected TTL in named blob DB", ttl, idConverterFactory.lastBlobInfo.getBlobProperties().getTimeToLiveInSeconds());
assertEquals("Unexpected response status", restResponseChannel.getStatus(), ResponseStatus.Ok);
} else {
TestUtils.assertException(ExecutionException.class, () -> future.get(TIMEOUT_SECS, TimeUnit.SECONDS), errorChecker);
}
}
use of com.github.ambry.router.FutureResult in project ambry by linkedin.
the class MockRouter method deleteBlob.
@Override
public Future<Void> deleteBlob(String blobId, String serviceId, Callback<Void> callback, QuotaChargeCallback quotaChargeCallback) {
lock.lock();
try {
FutureResult<Void> future = new FutureResult<>();
BlobInfoAndData blob = allBlobs.get(blobId);
if (blob == null) {
Exception e = new RouterException("NotFound", RouterErrorCode.BlobDoesNotExist);
future.done(null, e);
if (callback != null) {
callback.onCompletion(null, e);
}
return future;
}
allBlobs.remove(blobId);
future.done(null, null);
if (callback != null) {
callback.onCompletion(null, null);
}
return future;
} finally {
lock.unlock();
}
}
use of com.github.ambry.router.FutureResult in project ambry by linkedin.
the class MockRouter method putBlob.
@Override
public Future<String> putBlob(BlobProperties blobProperties, byte[] userMetadata, ReadableStreamChannel channel, PutBlobOptions options, Callback<String> callback, QuotaChargeCallback quotaChargeCallback) {
lock.lock();
try {
FutureResult<String> future = new FutureResult<>();
long size = channel.getSize();
try {
InputStream input = new ReadableStreamChannelInputStream(channel);
byte[] bytes = Utils.readBytesFromStream(input, (int) size);
BlobInfoAndData blob = new BlobInfoAndData(new BlobInfo(blobProperties, userMetadata), bytes);
String id;
do {
id = TestUtils.getRandomString(10);
} while (allBlobs.putIfAbsent(id, blob) != null);
future.done(id, null);
if (callback != null) {
callback.onCompletion(id, null);
}
return future;
} catch (Exception e) {
logger.error("Failed to put blob", e);
future.done(null, e);
if (callback != null) {
callback.onCompletion(null, e);
}
return future;
}
} finally {
lock.unlock();
}
}
use of com.github.ambry.router.FutureResult in project ambry by linkedin.
the class MockRouter method getBlob.
@Override
public Future<GetBlobResult> getBlob(String blobId, GetBlobOptions options, Callback<GetBlobResult> callback, QuotaChargeCallback quotaChargeCallback) {
lock.lock();
try {
BlobInfoAndData blob = allBlobs.get(blobId);
FutureResult<GetBlobResult> future = new FutureResult<>();
if (blob == null) {
Exception e = new RouterException("NotFound", RouterErrorCode.BlobDoesNotExist);
future.done(null, e);
if (callback != null) {
callback.onCompletion(null, e);
}
return future;
}
// Discard the options and only return the BlobAll.
ReadableStreamChannel channel = new ByteBufferReadableStreamChannel(ByteBuffer.wrap(blob.getData()));
GetBlobResult result = new GetBlobResult(blob.getBlobInfo(), channel);
future.done(result, null);
if (callback != null) {
callback.onCompletion(result, null);
}
return future;
} finally {
lock.unlock();
}
}
Aggregations