use of com.github.ambry.commons.ByteBufferReadableStreamChannel in project ambry by linkedin.
the class UndeleteHandlerTest method setupBlob.
/**
* Setup a blob and delete it so later we can undelete it.
* @throws Exception
*/
public void setupBlob() throws Exception {
ReadableStreamChannel channel = new ByteBufferReadableStreamChannel(ByteBuffer.wrap(BLOB_DATA));
blobId = router.putBlob(BLOB_PROPERTIES, new byte[0], channel, new PutBlobOptionsBuilder().build()).get(1, TimeUnit.SECONDS);
idConverterFactory.translation = blobId;
router.deleteBlob(blobId, SERVICE_ID).get(1, TimeUnit.SECONDS);
}
use of com.github.ambry.commons.ByteBufferReadableStreamChannel in project ambry by linkedin.
the class FrontendTestUrlSigningServiceFactory method releaseResourcesTest.
/**
* Tests releasing of resources if response submission fails.
* @throws JSONException
* @throws UnsupportedEncodingException
* @throws URISyntaxException
*/
@Test
public void releaseResourcesTest() throws JSONException, UnsupportedEncodingException, URISyntaxException {
responseHandler.shutdown();
// handleResponse of FrontendTestResponseHandler throws exception because it has been shutdown.
try {
RestRequest restRequest = createRestRequest(RestMethod.GET, "/", null, null);
MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
ReadableStreamChannel channel = new ByteBufferReadableStreamChannel(ByteBuffer.allocate(0));
assertTrue("RestRequest channel not open", restRequest.isOpen());
assertTrue("ReadableStreamChannel not open", channel.isOpen());
frontendRestRequestService.submitResponse(restRequest, restResponseChannel, channel, null);
assertFalse("ReadableStreamChannel is still open", channel.isOpen());
// null ReadableStreamChannel
restRequest = createRestRequest(RestMethod.GET, "/", null, null);
restResponseChannel = new MockRestResponseChannel();
assertTrue("RestRequest channel not open", restRequest.isOpen());
frontendRestRequestService.submitResponse(restRequest, restResponseChannel, null, null);
// bad RestRequest (close() throws IOException)
channel = new ByteBufferReadableStreamChannel(ByteBuffer.allocate(0));
restResponseChannel = new MockRestResponseChannel();
assertTrue("ReadableStreamChannel not open", channel.isOpen());
frontendRestRequestService.submitResponse(new BadRestRequest(), restResponseChannel, channel, null);
// bad ReadableStreamChannel (close() throws IOException)
restRequest = createRestRequest(RestMethod.GET, "/", null, null);
restResponseChannel = new MockRestResponseChannel();
assertTrue("RestRequest channel not open", restRequest.isOpen());
frontendRestRequestService.submitResponse(restRequest, restResponseChannel, new BadRSC(), null);
} finally {
frontendRestRequestService.setupResponseHandler(responseHandler);
responseHandler.start();
}
}
use of com.github.ambry.commons.ByteBufferReadableStreamChannel in project ambry by linkedin.
the class BadRestRequest method useServiceWithoutStartTest.
/**
* This tests for exceptions thrown when a {@link AsyncRequestResponseHandler} is used without calling
* {@link AsyncRequestResponseHandler#start()}first.
* @throws IOException
* @throws JSONException
* @throws URISyntaxException
*/
@Test
public void useServiceWithoutStartTest() throws IOException, JSONException, URISyntaxException {
AsyncRequestResponseHandler handler = getAsyncRequestResponseHandler(1);
RestRequest restRequest = createRestRequest(RestMethod.GET, "/", null, null);
try {
handler.handleRequest(restRequest, new MockRestResponseChannel());
fail("Should have thrown RestServiceException because the AsyncRequestResponseHandler has not been started");
} catch (RestServiceException e) {
assertEquals("The RestServiceErrorCode does not match", RestServiceErrorCode.ServiceUnavailable, e.getErrorCode());
}
restRequest = createRestRequest(RestMethod.GET, "/", null, null);
restRequest.getMetricsTracker().scalingMetricsTracker.markRequestReceived();
try {
handler.handleResponse(restRequest, new MockRestResponseChannel(), new ByteBufferReadableStreamChannel(ByteBuffer.allocate(0)), null);
fail("Should have thrown RestServiceException because the AsyncRequestResponseHandler has not been started");
} catch (RestServiceException e) {
assertEquals("The RestServiceErrorCode does not match", RestServiceErrorCode.ServiceUnavailable, e.getErrorCode());
}
}
use of com.github.ambry.commons.ByteBufferReadableStreamChannel in project ambry by linkedin.
the class ChunkFillTest method fillChunksAndAssertSuccess.
/**
* Create a {@link PutOperation} and pass in a channel with the blobSize set by the caller; and test the chunk
* filling flow for puts.
* Note that this test is for the chunk filling flow, not for the ChunkFiller thread (which never gets exercised,
* as we do not even instantiate the {@link PutManager})
*/
private void fillChunksAndAssertSuccess() throws Exception {
VerifiableProperties vProps = getNonBlockingRouterProperties();
MockClusterMap mockClusterMap = new MockClusterMap();
RouterConfig routerConfig = new RouterConfig(vProps);
routerMetrics = new NonBlockingRouterMetrics(mockClusterMap, routerConfig);
ResponseHandler responseHandler = new ResponseHandler(mockClusterMap);
short accountId = Utils.getRandomShort(random);
short containerId = Utils.getRandomShort(random);
BlobProperties putBlobProperties = new BlobProperties(blobSize, "serviceId", "memberId", "contentType", false, Utils.Infinite_Time, accountId, containerId, testEncryption, null, null, null);
Random random = new Random();
byte[] putUserMetadata = new byte[10];
random.nextBytes(putUserMetadata);
putContent = new byte[blobSize];
random.nextBytes(putContent);
final ReadableStreamChannel putChannel = new ByteBufferReadableStreamChannel(ByteBuffer.wrap(putContent));
FutureResult<String> futureResult = new FutureResult<String>();
MockTime time = new MockTime();
MockNetworkClientFactory networkClientFactory = new MockNetworkClientFactory(vProps, null, 0, 0, 0, null, time);
if (testEncryption) {
kms = new MockKeyManagementService(new KMSConfig(vProps), TestUtils.getRandomKey(SingleKeyManagementServiceTest.DEFAULT_KEY_SIZE_CHARS));
cryptoService = new MockCryptoService(new CryptoServiceConfig(vProps));
cryptoJobHandler = new CryptoJobHandler(CryptoJobHandlerTest.DEFAULT_THREAD_COUNT);
}
MockRouterCallback routerCallback = new MockRouterCallback(networkClientFactory.getNetworkClient(), Collections.EMPTY_LIST);
PutOperation op = PutOperation.forUpload(routerConfig, routerMetrics, mockClusterMap, new LoggingNotificationSystem(), new InMemAccountService(true, false), putUserMetadata, putChannel, PutBlobOptions.DEFAULT, futureResult, null, routerCallback, null, kms, cryptoService, cryptoJobHandler, time, putBlobProperties, MockClusterMap.DEFAULT_PARTITION_CLASS, quotaChargeCallback);
op.startOperation();
numChunks = RouterUtils.getNumChunksForBlobAndChunkSize(blobSize, chunkSize);
compositeBuffers = new ByteBuf[numChunks];
compositeEncryptionKeys = new ByteBuffer[numChunks];
compositeBlobIds = new BlobId[numChunks];
final AtomicReference<Exception> operationException = new AtomicReference<Exception>(null);
int chunksLeftToBeFilled = numChunks;
do {
if (testEncryption) {
int chunksPerBatch = Math.min(routerConfig.routerMaxInMemPutChunks, chunksLeftToBeFilled);
CountDownLatch onPollLatch = new CountDownLatch(chunksPerBatch);
routerCallback.setOnPollLatch(onPollLatch);
op.fillChunks();
Assert.assertTrue("Latch should have been zeroed out", onPollLatch.await(1000, TimeUnit.MILLISECONDS));
chunksLeftToBeFilled -= chunksPerBatch;
} else {
op.fillChunks();
}
// since the channel is ByteBuffer based.
for (PutOperation.PutChunk putChunk : op.putChunks) {
if (putChunk.isFree()) {
continue;
}
Assert.assertEquals("Chunk should be ready.", PutOperation.ChunkState.Ready, putChunk.getState());
ByteBuf buf = putChunk.buf.retainedDuplicate();
totalSizeWritten += buf.readableBytes();
compositeBuffers[putChunk.getChunkIndex()] = buf;
if (testEncryption) {
compositeEncryptionKeys[putChunk.getChunkIndex()] = putChunk.encryptedPerBlobKey.duplicate();
compositeBlobIds[putChunk.getChunkIndex()] = putChunk.chunkBlobId;
}
putChunk.clear();
}
} while (!op.isChunkFillingDone());
if (!testEncryption) {
Assert.assertEquals("total size written out should match the blob size", blobSize, totalSizeWritten);
}
// for encrypted path, size will be implicitly tested via assertDataIdentity
Exception exception = operationException.get();
if (exception != null) {
throw exception;
}
assertDataIdentity(mockClusterMap);
}
use of com.github.ambry.commons.ByteBufferReadableStreamChannel in project ambry by linkedin.
the class MockReadableStreamChannel method testBadCallback.
/**
* Test that a bad user defined callback will not crash the router.
* @throws Exception
*/
@Test
public void testBadCallback() throws Exception {
RequestAndResult req = new RequestAndResult(chunkSize * 5 + random.nextInt(chunkSize - 1) + 1);
router = getNonBlockingRouter();
final CountDownLatch callbackCalled = new CountDownLatch(1);
requestAndResultsList.clear();
for (int i = 0; i < 4; i++) {
requestAndResultsList.add(new RequestAndResult(chunkSize + random.nextInt(5) * random.nextInt(chunkSize)));
}
instantiateNewRouterForPuts = false;
ReadableStreamChannel putChannel = new ByteBufferReadableStreamChannel(ByteBuffer.wrap(req.putContent));
Future future = router.putBlob(req.putBlobProperties, req.putUserMetadata, putChannel, req.options, (result, exception) -> {
callbackCalled.countDown();
throw new RuntimeException("Throwing an exception in the user callback");
}, new QuotaChargeCallback() {
@Override
public void charge(long chunkSize) {
}
@Override
public void charge() {
}
@Override
public boolean check() {
return false;
}
@Override
public boolean quotaExceedAllowed() {
return false;
}
@Override
public QuotaResource getQuotaResource() throws QuotaException {
return null;
}
@Override
public QuotaMethod getQuotaMethod() {
return null;
}
});
submitPutsAndAssertSuccess(false);
// future.get() for operation with bad callback should still succeed
future.get();
Assert.assertTrue("Callback not called.", callbackCalled.await(MAX_WAIT_MS, TimeUnit.MILLISECONDS));
assertEquals("All operations should be finished.", 0, router.getOperationsCount());
Assert.assertTrue("Router should not be closed", router.isOpen());
// Test that PutManager is still operational
requestAndResultsList.clear();
requestAndResultsList.add(new RequestAndResult(chunkSize + random.nextInt(5) * random.nextInt(chunkSize)));
instantiateNewRouterForPuts = false;
submitPutsAndAssertSuccess(true);
}
Aggregations