use of com.github.ambry.config.RouterConfig in project ambry by linkedin.
the class MockRouterCallback method testBlobAuthorizationFailureOverrideAll.
/**
* Test the case where servers return different {@link ServerErrorCode} or success, and the {@link GetBlobInfoOperation}
* is able to resolve and conclude the correct {@link RouterErrorCode}. The get blob operation should be able
* to resolve the router error code as {@code Blob_Authorization_Failure}.
* @throws Exception
*/
@Test
public void testBlobAuthorizationFailureOverrideAll() throws Exception {
// set it to 2 for more coverage
successTarget = 2;
Properties props = getNonBlockingRouterProperties(true);
routerConfig = new RouterConfig(new VerifiableProperties(props));
ServerErrorCode[] serverErrorCodes = new ServerErrorCode[9];
serverErrorCodes[0] = ServerErrorCode.Blob_Not_Found;
serverErrorCodes[1] = ServerErrorCode.Data_Corrupt;
serverErrorCodes[2] = ServerErrorCode.IO_Error;
serverErrorCodes[3] = ServerErrorCode.Partition_Unknown;
serverErrorCodes[4] = ServerErrorCode.Disk_Unavailable;
serverErrorCodes[5] = ServerErrorCode.Blob_Authorization_Failure;
serverErrorCodes[6] = ServerErrorCode.Unknown_Error;
serverErrorCodes[7] = ServerErrorCode.Unknown_Error;
serverErrorCodes[8] = ServerErrorCode.No_Error;
testErrorPrecedence(serverErrorCodes, RouterErrorCode.BlobAuthorizationFailure);
}
use of com.github.ambry.config.RouterConfig in project ambry by linkedin.
the class MockRouterCallback method testIOErrorAndBlobNotFoundInOriginDc.
/**
* Test the case where origin replicas return Blob_Not_found and the rest returns IO_Error.
* @throws Exception
*/
@Test
public void testIOErrorAndBlobNotFoundInOriginDc() throws Exception {
assumeTrue(operationTrackerType.equals(AdaptiveOperationTracker.class.getSimpleName()));
correlationIdToGetOperation.clear();
// Pick a remote DC as the new local DC.
String newLocal = "DC1";
String oldLocal = localDcName;
Properties props = getNonBlockingRouterProperties(true);
props.setProperty("router.datacenter.name", newLocal);
routerConfig = new RouterConfig(new VerifiableProperties(props));
for (MockServer server : mockServerLayout.getMockServers()) {
if (server.getDataCenter().equals(oldLocal)) {
// for origin DC, always return Blob_Not_Found;
server.setServerErrorForAllRequests(ServerErrorCode.Blob_Not_Found);
} else {
// otherwise, return IO_Error.
server.setServerErrorForAllRequests(ServerErrorCode.IO_Error);
}
}
NonBlockingRouter.currentOperationsCount.incrementAndGet();
GetBlobInfoOperation op = new GetBlobInfoOperation(routerConfig, routerMetrics, mockClusterMap, responseHandler, blobId, options, null, routerCallback, kms, cryptoService, cryptoJobHandler, time, false, quotaChargeCallback);
requestRegistrationCallback.setRequestsToSend(new ArrayList<>());
AdaptiveOperationTracker tracker = (AdaptiveOperationTracker) op.getOperationTrackerInUse();
completeOp(op);
RouterException routerException = (RouterException) op.getOperationException();
// error code should be OperationTimedOut because it precedes BlobDoesNotExist
Assert.assertEquals(RouterErrorCode.BlobDoesNotExist, routerException.getErrorCode());
// localReplica now becomes remote replica.
Assert.assertEquals("The number of data points in remote colo latency histogram is not expected", 3, tracker.getLatencyHistogram(localReplica).getCount());
props = getNonBlockingRouterProperties(true);
props.setProperty("router.datacenter.name", oldLocal);
routerConfig = new RouterConfig(new VerifiableProperties(props));
}
use of com.github.ambry.config.RouterConfig in project ambry by linkedin.
the class MockRouterCallback method testSuccessInThePresenceOfVariousErrors.
/**
* Test the case with multiple errors (server level and partition level) from multiple servers,
* with just one server returning a successful response. The operation should succeed.
* @throws Exception
*/
@Test
public void testSuccessInThePresenceOfVariousErrors() throws Exception {
// The put for the blob being requested happened.
String dcWherePutHappened = routerConfig.routerDatacenterName;
// test requests coming in from local dc as well as cross-colo.
Properties props = getNonBlockingRouterProperties(true);
props.setProperty("router.datacenter.name", "DC1");
routerConfig = new RouterConfig(new VerifiableProperties(props));
testVariousErrors(dcWherePutHappened);
props = getNonBlockingRouterProperties(true);
props.setProperty("router.datacenter.name", "DC2");
routerConfig = new RouterConfig(new VerifiableProperties(props));
testVariousErrors(dcWherePutHappened);
props = getNonBlockingRouterProperties(true);
props.setProperty("router.datacenter.name", "DC3");
routerConfig = new RouterConfig(new VerifiableProperties(props));
testVariousErrors(dcWherePutHappened);
}
use of com.github.ambry.config.RouterConfig in project ambry by linkedin.
the class OperationTrackerTest method getOperationTracker.
/**
* Returns the right {@link OperationTracker} based on {@link #operationTrackerType}.
* @param crossColoEnabled {@code true} if cross colo needs to be enabled. {@code false} otherwise.
* @param successTargetForGet the number of successful responses required for GET operation to succeed.
* @param parallelism the number of parallel requests that can be in flight.
* @param routerOperation the {@link RouterOperation} associate with this request.
* @param includeDownReplicas whether to include down replicas in operation tracker.
* @return the right {@link OperationTracker} based on {@link #operationTrackerType}.
*/
private OperationTracker getOperationTracker(boolean crossColoEnabled, int successTargetForGet, int parallelism, RouterOperation routerOperation, boolean includeDownReplicas) {
Properties props = new Properties();
props.setProperty(RouterConfig.ROUTER_HOSTNAME, "localhost");
props.setProperty(RouterConfig.ROUTER_DATACENTER_NAME, localDcName);
props.setProperty(RouterConfig.ROUTER_GET_CROSS_DC_ENABLED, Boolean.toString(crossColoEnabled));
props.setProperty(RouterConfig.ROUTER_GET_SUCCESS_TARGET, Integer.toString(successTargetForGet));
props.setProperty(RouterConfig.ROUTER_GET_REQUEST_PARALLELISM, Integer.toString(parallelism));
props.setProperty(RouterConfig.ROUTER_PUT_REQUEST_PARALLELISM, Integer.toString(parallelism));
props.setProperty(RouterConfig.ROUTER_LATENCY_TOLERANCE_QUANTILE, Double.toString(QUANTILE));
props.setProperty(RouterConfig.ROUTER_OPERATION_TRACKER_MAX_INFLIGHT_REQUESTS, Integer.toString(parallelism));
props.setProperty(RouterConfig.ROUTER_OPERATION_TRACKER_TERMINATE_ON_NOT_FOUND_ENABLED, Boolean.toString(true));
props.setProperty(RouterConfig.ROUTER_GET_ELIGIBLE_REPLICAS_BY_STATE_ENABLED, Boolean.toString(replicasStateEnabled));
props.setProperty(RouterConfig.ROUTER_PUT_USE_DYNAMIC_SUCCESS_TARGET, Boolean.toString(useDynamicTargetForPut));
props.setProperty(RouterConfig.ROUTER_CROSS_COLO_REQUEST_TO_DC_WITH_MOST_REPLICAS, Boolean.toString(chooseDcWithMostReplicas));
props.setProperty(RouterConfig.ROUTER_OPERATION_TRACKER_INCLUDE_DOWN_REPLICAS, Boolean.toString(includeDownReplicas));
RouterConfig routerConfig = new RouterConfig(new VerifiableProperties(props));
NonBlockingRouterMetrics routerMetrics = new NonBlockingRouterMetrics(mockClusterMap, routerConfig);
OperationTracker tracker;
switch(operationTrackerType) {
case SIMPLE_OP_TRACKER:
tracker = new SimpleOperationTracker(routerConfig, routerOperation, mockPartition, originatingDcName, true, routerMetrics);
break;
case ADAPTIVE_OP_TRACKER:
// for now adaptive operation tracker only applies to GetOperation.
if (!EnumSet.of(RouterOperation.GetBlobInfoOperation, RouterOperation.GetBlobOperation).contains(routerOperation)) {
throw new IllegalArgumentException("Adaptive tracker currently is not used for " + routerOperation);
}
tracker = new AdaptiveOperationTracker(routerConfig, routerMetrics, routerOperation, mockPartition, originatingDcName, time);
break;
default:
throw new IllegalArgumentException("Unrecognized operation tracker type - " + operationTrackerType);
}
return tracker;
}
use of com.github.ambry.config.RouterConfig in project ambry by linkedin.
the class MockReadableStreamChannel method testChunkFillerSleepWithBuildingChunk.
/**
* Test when channel is closed while chunk filler thread is not responding, PutManager would release the data chunks.
* @throws Exception
*/
@Test
public void testChunkFillerSleepWithBuildingChunk() throws Exception {
VerifiableProperties vProps = getRouterConfigInVerifiableProperties();
MockNetworkClient networkClient = new MockNetworkClientFactory(vProps, mockSelectorState, MAX_PORTS_PLAIN_TEXT, MAX_PORTS_SSL, CHECKOUT_TIMEOUT_MS, mockServerLayout, mockTime).getMockNetworkClient();
PutManager manager = new PutManager(mockClusterMap, new ResponseHandler(mockClusterMap), notificationSystem, new RouterConfig(vProps), new NonBlockingRouterMetrics(mockClusterMap, null), new RouterCallback(networkClient, null), "0", kms, cryptoService, cryptoJobHandler, accountService, mockTime, MockClusterMap.DEFAULT_PARTITION_CLASS);
BlobProperties blobProperties = new BlobProperties(-1, "serviceId", "memberId", "contentType", false, Utils.Infinite_Time, Utils.getRandomShort(TestUtils.RANDOM), Utils.getRandomShort(TestUtils.RANDOM), false, null, null, null);
byte[] userMetadata = new byte[10];
byte[] content = new byte[chunkSize / 4];
random.nextBytes(content);
MockReadableStreamChannel channel = // make sure we are not sending the entire chunk
new MockReadableStreamChannel(chunkSize / 2, false);
FutureResult<String> future = new FutureResult<>();
manager.submitPutBlobOperation(blobProperties, userMetadata, channel, PutBlobOptions.DEFAULT, future, null, null);
channel.write(ByteBuffer.wrap(content));
// Sleep until
// Op has a building chunk
// Chunk Filler is sleeping
PutOperation op = manager.getPutOperations().iterator().next();
Assert.assertFalse(op.isOperationComplete());
PutOperation.PutChunk putChunk = op.putChunks.iterator().next();
Assert.assertTrue(putChunk.isBuilding());
manager.forceChunkFillerThreadToSleep();
Thread chunkFillerThread = TestUtils.getThreadByThisName("ChunkFillerThread");
Assert.assertTrue("ChunkFillerThread should have gone to WAITING state as there are no active operations", waitForThreadState(chunkFillerThread, Thread.State.WAITING));
channel.beBad();
channel.write(ByteBuffer.wrap(content));
Assert.assertTrue(op.isOperationComplete());
Assert.assertTrue(putChunk.isBuilding());
manager.poll(new ArrayList<>(), new HashSet<>());
Assert.assertTrue(putChunk.isDataReleased());
Assert.assertEquals(0, manager.getPutOperations().size());
// Make sure this static field's value stay the same
NonBlockingRouter.currentOperationsCount.incrementAndGet();
manager.close();
}
Aggregations