Search in sources :

Example 1 with GetResponse

use of com.github.ambry.protocol.GetResponse in project ambry by linkedin.

the class ReplicaThread method getMessagesForMissingKeys.

/**
 * Gets the messages for the keys that are missing from the local store by issuing a {@link GetRequest} to the remote
 * node, if there are any missing keys. If there are no missing keys to be fetched, then no request is issued and a
 * null response is returned.
 * @param connectedChannel The connection channel to the remote node
 * @param exchangeMetadataResponseList The list of metadata response from the remote node
 * @param replicasToReplicatePerNode The list of remote replicas for the remote node
 * @param remoteNode The remote node from which replication needs to happen
 * @return The response that contains the missing messages; or null if no request was issued because there were no
 * keys missing.
 * @throws ReplicationException
 * @throws IOException
 */
private GetResponse getMessagesForMissingKeys(ConnectedChannel connectedChannel, List<ExchangeMetadataResponse> exchangeMetadataResponseList, List<RemoteReplicaInfo> replicasToReplicatePerNode, DataNodeId remoteNode) throws ReplicationException, IOException {
    List<PartitionRequestInfo> partitionRequestInfoList = new ArrayList<PartitionRequestInfo>();
    for (int i = 0; i < exchangeMetadataResponseList.size(); i++) {
        ExchangeMetadataResponse exchangeMetadataResponse = exchangeMetadataResponseList.get(i);
        RemoteReplicaInfo remoteReplicaInfo = replicasToReplicatePerNode.get(i);
        if (exchangeMetadataResponse.serverErrorCode == ServerErrorCode.No_Error) {
            Set<StoreKey> missingStoreKeys = exchangeMetadataResponse.missingStoreKeys;
            if (missingStoreKeys.size() > 0) {
                ArrayList<BlobId> keysToFetch = new ArrayList<BlobId>();
                for (StoreKey storeKey : missingStoreKeys) {
                    keysToFetch.add((BlobId) storeKey);
                }
                PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(remoteReplicaInfo.getReplicaId().getPartitionId(), keysToFetch);
                partitionRequestInfoList.add(partitionRequestInfo);
            }
        }
    }
    GetResponse getResponse = null;
    if (!partitionRequestInfoList.isEmpty()) {
        GetRequest getRequest = new GetRequest(correlationIdGenerator.incrementAndGet(), "replication-fetch-" + dataNodeId.getHostname(), MessageFormatFlags.All, partitionRequestInfoList, GetOption.None);
        long startTime = SystemTime.getInstance().milliseconds();
        try {
            connectedChannel.send(getRequest);
            ChannelOutput channelOutput = connectedChannel.receive();
            getResponse = GetResponse.readFrom(new DataInputStream(channelOutput.getInputStream()), clusterMap);
            long getRequestTime = SystemTime.getInstance().milliseconds() - startTime;
            replicationMetrics.updateGetRequestTime(getRequestTime, replicatingFromRemoteColo, replicatingOverSsl, datacenterName);
            if (getResponse.getError() != ServerErrorCode.No_Error) {
                logger.error("Remote node: " + remoteNode + " Thread name: " + threadName + " Remote replicas: " + replicasToReplicatePerNode + " GetResponse from replication: " + getResponse.getError());
                throw new ReplicationException(" Get Request returned error when trying to get missing keys " + getResponse.getError());
            }
        } catch (IOException e) {
            responseHandler.onEvent(replicasToReplicatePerNode.get(0).getReplicaId(), e);
            throw e;
        }
    }
    return getResponse;
}
Also used : ChannelOutput(com.github.ambry.network.ChannelOutput) ArrayList(java.util.ArrayList) IOException(java.io.IOException) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) DataInputStream(java.io.DataInputStream) StoreKey(com.github.ambry.store.StoreKey) GetResponse(com.github.ambry.protocol.GetResponse) GetRequest(com.github.ambry.protocol.GetRequest) BlobId(com.github.ambry.commons.BlobId)

Example 2 with GetResponse

use of com.github.ambry.protocol.GetResponse in project ambry by linkedin.

the class GetBlobResultInternal method extractGetResponseAndNotifyResponseHandler.

/**
 * Extract the {@link GetResponse} from the given {@link ResponseInfo}
 * @param responseInfo the {@link ResponseInfo} from which the {@link GetResponse} is to be extracted.
 * @return the extracted {@link GetResponse} if there is one; null otherwise.
 */
private GetResponse extractGetResponseAndNotifyResponseHandler(ResponseInfo responseInfo) {
    GetResponse getResponse = null;
    ReplicaId replicaId = ((RouterRequestInfo) responseInfo.getRequestInfo()).getReplicaId();
    NetworkClientErrorCode networkClientErrorCode = responseInfo.getError();
    if (networkClientErrorCode == null) {
        try {
            getResponse = GetResponse.readFrom(new DataInputStream(new ByteBufferInputStream(responseInfo.getResponse())), clusterMap);
            ServerErrorCode serverError = getResponse.getError();
            if (serverError == ServerErrorCode.No_Error) {
                serverError = getResponse.getPartitionResponseInfoList().get(0).getErrorCode();
            }
            responseHandler.onEvent(replicaId, serverError);
        } catch (Exception e) {
            // Ignore. There is no value in notifying the response handler.
            logger.error("Response deserialization received unexpected error", e);
            routerMetrics.responseDeserializationErrorCount.inc();
        }
    } else {
        responseHandler.onEvent(replicaId, networkClientErrorCode);
    }
    return getResponse;
}
Also used : NetworkClientErrorCode(com.github.ambry.network.NetworkClientErrorCode) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) DataInputStream(java.io.DataInputStream) GetResponse(com.github.ambry.protocol.GetResponse) ReplicaId(com.github.ambry.clustermap.ReplicaId) ServerErrorCode(com.github.ambry.commons.ServerErrorCode)

Example 3 with GetResponse

use of com.github.ambry.protocol.GetResponse 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());
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) ArrayList(java.util.ArrayList) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) RequestInfo(com.github.ambry.network.RequestInfo) CountDownLatch(java.util.concurrent.CountDownLatch) DataInputStream(java.io.DataInputStream) GetResponse(com.github.ambry.protocol.GetResponse)

Example 4 with GetResponse

use of com.github.ambry.protocol.GetResponse 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());
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) ArrayList(java.util.ArrayList) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) RequestInfo(com.github.ambry.network.RequestInfo) DataInputStream(java.io.DataInputStream) GetResponse(com.github.ambry.protocol.GetResponse) PutManagerTest(com.github.ambry.router.PutManagerTest) Test(org.junit.Test)

Example 5 with GetResponse

use of com.github.ambry.protocol.GetResponse 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);
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) ArrayList(java.util.ArrayList) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) RequestInfo(com.github.ambry.network.RequestInfo) DataInputStream(java.io.DataInputStream) GetResponse(com.github.ambry.protocol.GetResponse)

Aggregations

GetResponse (com.github.ambry.protocol.GetResponse)44 GetRequest (com.github.ambry.protocol.GetRequest)28 PartitionRequestInfo (com.github.ambry.protocol.PartitionRequestInfo)28 ArrayList (java.util.ArrayList)28 DataInputStream (java.io.DataInputStream)26 BlobId (com.github.ambry.commons.BlobId)22 BlobProperties (com.github.ambry.messageformat.BlobProperties)18 NettyByteBufDataInputStream (com.github.ambry.utils.NettyByteBufDataInputStream)18 ResponseInfo (com.github.ambry.network.ResponseInfo)14 VerifiableProperties (com.github.ambry.config.VerifiableProperties)13 ByteBufferInputStream (com.github.ambry.utils.ByteBufferInputStream)12 PartitionId (com.github.ambry.clustermap.PartitionId)11 PutRequest (com.github.ambry.protocol.PutRequest)11 IOException (java.io.IOException)11 ByteBuffer (java.nio.ByteBuffer)11 Properties (java.util.Properties)11 MessageFormatException (com.github.ambry.messageformat.MessageFormatException)10 RequestInfo (com.github.ambry.network.RequestInfo)10 DeleteResponse (com.github.ambry.protocol.DeleteResponse)10 PutResponse (com.github.ambry.protocol.PutResponse)10