use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class MockRouterCallback method assertOperationFailure.
/**
* Assert that operation fails with the expected error code
* @param errorCode expected error code on failure
* @throws RouterException
*/
private void assertOperationFailure(RouterErrorCode errorCode) throws RouterException, IOException, InterruptedException {
NonBlockingRouter.currentOperationsCount.incrementAndGet();
GetBlobInfoOperation op = new GetBlobInfoOperation(routerConfig, routerMetrics, mockClusterMap, responseHandler, blobId, options, null, routerCallback, kms, cryptoService, cryptoJobHandler, time);
ArrayList<RequestInfo> requestListToFill = new ArrayList<>();
requestRegistrationCallback.requestListToFill = requestListToFill;
op.poll(requestRegistrationCallback);
Assert.assertEquals("There should only be as many requests at this point as requestParallelism", requestParallelism, correlationIdToGetOperation.size());
CountDownLatch onPollLatch = new CountDownLatch(1);
routerCallback.setOnPollLatch(onPollLatch);
List<ResponseInfo> responses = sendAndWaitForResponses(requestListToFill);
for (ResponseInfo responseInfo : responses) {
GetResponse getResponse = responseInfo.getError() == null ? GetResponse.readFrom(new DataInputStream(new ByteBufferInputStream(responseInfo.getResponse())), mockClusterMap) : null;
op.handleResponse(responseInfo, getResponse);
if (op.isOperationComplete()) {
break;
}
}
if (!op.isOperationComplete()) {
Assert.assertTrue("Latch should have been zeroed ", onPollLatch.await(500, TimeUnit.MILLISECONDS));
op.poll(requestRegistrationCallback);
}
Assert.assertTrue("Operation should be complete at this time", op.isOperationComplete());
RouterException routerException = (RouterException) op.getOperationException();
Assert.assertEquals(errorCode, routerException.getErrorCode());
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class MockRouterCallback method testBlobNotFoundCase.
/**
* Test the case where every server returns Blob_Not_Found. All servers must have been contacted,
* due to cross-colo proxying.
* @throws Exception
*/
@Test
public void testBlobNotFoundCase() throws Exception {
NonBlockingRouter.currentOperationsCount.incrementAndGet();
GetBlobInfoOperation op = new GetBlobInfoOperation(routerConfig, routerMetrics, mockClusterMap, responseHandler, blobId, options, null, routerCallback, kms, cryptoService, cryptoJobHandler, time);
ArrayList<RequestInfo> requestListToFill = new ArrayList<>();
requestRegistrationCallback.requestListToFill = requestListToFill;
for (MockServer server : mockServerLayout.getMockServers()) {
server.setServerErrorForAllRequests(ServerErrorCode.Blob_Not_Found);
}
while (!op.isOperationComplete()) {
op.poll(requestRegistrationCallback);
List<ResponseInfo> responses = sendAndWaitForResponses(requestListToFill);
for (ResponseInfo responseInfo : responses) {
GetResponse getResponse = responseInfo.getError() == null ? GetResponse.readFrom(new DataInputStream(new ByteBufferInputStream(responseInfo.getResponse())), mockClusterMap) : null;
op.handleResponse(responseInfo, getResponse);
if (op.isOperationComplete()) {
break;
}
}
}
Assert.assertEquals("Must have attempted sending requests to all replicas", replicasCount, correlationIdToGetOperation.size());
Assert.assertTrue("Operation should be complete at this time", op.isOperationComplete());
RouterException routerException = (RouterException) op.getOperationException();
Assert.assertEquals(RouterErrorCode.BlobDoesNotExist, routerException.getErrorCode());
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class MockRouterCallback method testVariousErrors.
private void testVariousErrors(String dcWherePutHappened) throws Exception {
NonBlockingRouter.currentOperationsCount.incrementAndGet();
GetBlobInfoOperation op = new GetBlobInfoOperation(routerConfig, routerMetrics, mockClusterMap, responseHandler, blobId, options, null, routerCallback, kms, cryptoService, cryptoJobHandler, time);
ArrayList<RequestInfo> requestListToFill = new ArrayList<>();
requestRegistrationCallback.requestListToFill = requestListToFill;
ArrayList<MockServer> mockServers = new ArrayList<>(mockServerLayout.getMockServers());
// set the status to various server level or partition level errors (not Blob_Deleted or Blob_Expired).
mockServers.get(0).setServerErrorForAllRequests(ServerErrorCode.Unknown_Error);
mockServers.get(1).setServerErrorForAllRequests(ServerErrorCode.Unknown_Error);
mockServers.get(2).setServerErrorForAllRequests(ServerErrorCode.IO_Error);
mockServers.get(3).setServerErrorForAllRequests(ServerErrorCode.Blob_Not_Found);
mockServers.get(4).setServerErrorForAllRequests(ServerErrorCode.Data_Corrupt);
mockServers.get(5).setServerErrorForAllRequests(ServerErrorCode.Blob_Not_Found);
mockServers.get(6).setServerErrorForAllRequests(ServerErrorCode.Blob_Not_Found);
mockServers.get(7).setServerErrorForAllRequests(ServerErrorCode.Disk_Unavailable);
mockServers.get(8).setServerErrorForAllRequests(ServerErrorCode.Unknown_Error);
// clear the hard error in one of the servers in the datacenter where the put happened.
for (int i = 0; i < mockServers.size(); i++) {
MockServer mockServer = mockServers.get(i);
if (mockServer.getDataCenter().equals(dcWherePutHappened)) {
mockServer.setServerErrorForAllRequests(ServerErrorCode.No_Error);
break;
}
}
while (!op.isOperationComplete()) {
op.poll(requestRegistrationCallback);
List<ResponseInfo> responses = sendAndWaitForResponses(requestListToFill);
for (ResponseInfo responseInfo : responses) {
GetResponse getResponse = responseInfo.getError() == null ? GetResponse.readFrom(new DataInputStream(new ByteBufferInputStream(responseInfo.getResponse())), mockClusterMap) : null;
op.handleResponse(responseInfo, getResponse);
if (op.isOperationComplete()) {
break;
}
}
}
Assert.assertTrue("Operation should be complete at this time", op.isOperationComplete());
assertSuccess(op);
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class NonBlockingRouterTest method testResponseDeserializationError.
/**
* Test that operations succeed even in the presence of responses that are corrupt and fail to deserialize.
* @param opHelper the {@link OperationHelper}
* @param networkClient the {@link NetworkClient}
* @param blobId the id of the blob to get/delete. For puts, this will be null.
* @throws Exception
*/
private void testResponseDeserializationError(OperationHelper opHelper, NetworkClient networkClient, BlobId blobId) throws Exception {
mockSelectorState.set(MockSelectorState.Good);
FutureResult futureResult = opHelper.submitOperation(blobId);
int requestParallelism = opHelper.requestParallelism;
List<RequestInfo> allRequests = new ArrayList<>();
long loopStartTimeMs = SystemTime.getInstance().milliseconds();
while (allRequests.size() < requestParallelism) {
if (loopStartTimeMs + AWAIT_TIMEOUT_MS < SystemTime.getInstance().milliseconds()) {
Assert.fail("Waited too long for requests.");
}
opHelper.pollOpManager(allRequests);
}
List<ResponseInfo> responseInfoList = new ArrayList<>();
loopStartTimeMs = SystemTime.getInstance().milliseconds();
do {
if (loopStartTimeMs + AWAIT_TIMEOUT_MS < SystemTime.getInstance().milliseconds()) {
Assert.fail("Waited too long for the response.");
}
responseInfoList.addAll(networkClient.sendAndPoll(allRequests, 10));
allRequests.clear();
} while (responseInfoList.size() < requestParallelism);
// corrupt the first response.
ByteBuffer response = responseInfoList.get(0).getResponse();
byte b = response.get(response.limit() - 1);
response.put(response.limit() - 1, (byte) ~b);
for (ResponseInfo responseInfo : responseInfoList) {
opHelper.handleResponse(responseInfo);
}
allRequests.clear();
if (testEncryption) {
opHelper.awaitOpCompletionOrTimeOut(futureResult);
} else {
opHelper.pollOpManager(allRequests);
}
try {
futureResult.get(AWAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
Assert.fail("Operation should have succeeded with one corrupt response");
}
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class ServerAdminTool method sendRequestGetResponse.
/**
* Sends {@code request} to {@code dataNodeId} and returns the response as a {@link ByteBuffer}.
* @param dataNodeId the {@link DataNodeId} to contact.
* @param partitionId the {@link PartitionId} associated with request.
* @param request the request to send.
* @return the response as a {@link ResponseInfo} if the response was successfully received. {@code null} otherwise.
* @throws TimeoutException
*/
private ResponseInfo sendRequestGetResponse(DataNodeId dataNodeId, PartitionId partitionId, SendWithCorrelationId request) throws TimeoutException {
ReplicaId replicaId = getReplicaFromNode(dataNodeId, partitionId);
String hostname = dataNodeId.getHostname();
Port port = dataNodeId.getPortToConnectTo();
String identifier = hostname + ":" + port.getPort();
RequestInfo requestInfo = new RequestInfo(hostname, port, request, replicaId, null);
List<RequestInfo> requestInfos = Collections.singletonList(requestInfo);
ResponseInfo responseInfo = null;
long startTimeMs = time.milliseconds();
do {
if (time.milliseconds() - startTimeMs > OPERATION_TIMEOUT_MS) {
throw new TimeoutException(identifier + ": Operation did not complete within " + OPERATION_TIMEOUT_MS + " ms");
}
List<ResponseInfo> responseInfos = networkClient.sendAndPoll(requestInfos, Collections.emptySet(), POLL_TIMEOUT_MS);
if (responseInfos.size() > 1) {
// May need to relax this check because response list may contain more than 1 response
throw new IllegalStateException("Received more than one response even though a single request was sent");
} else if (!responseInfos.isEmpty()) {
responseInfo = responseInfos.get(0);
}
requestInfos = Collections.emptyList();
} while (responseInfo == null);
if (responseInfo.getError() != null) {
throw new IllegalStateException(identifier + ": Encountered error while trying to send request - " + responseInfo.getError());
}
return responseInfo;
}
Aggregations