Search in sources :

Example 31 with GetResponse

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

the class MockRouterCallback method testErrorPrecedence.

/**
 * Help test error precedence.
 * @param serverErrorCodesInOrder the list of error codes to set the mock servers with.
 * @param expectedErrorCode the expected router error code for the operation.
 * @throws Exception
 */
private void testErrorPrecedence(ServerErrorCode[] serverErrorCodesInOrder, RouterErrorCode expectedErrorCode) 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;
    int i = 0;
    for (MockServer server : mockServerLayout.getMockServers()) {
        server.setServerErrorForAllRequests(serverErrorCodesInOrder[i++]);
    }
    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;
            }
        }
    }
    RouterException routerException = (RouterException) op.getOperationException();
    Assert.assertEquals(expectedErrorCode, 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)

Example 32 with GetResponse

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

the class InMemoryCloudDestinationErrorSimulationTest method testGetBlobErrorSimulation.

/**
 * test error simulation for GetBlobRequest
 * @throws Exception
 */
@Test
public void testGetBlobErrorSimulation() throws Exception {
    BlobId blobId = doPut(partitionId);
    ArrayList<BlobId> blobIdList = new ArrayList<BlobId>();
    blobIdList.add(blobId);
    PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(partitionId, blobIdList);
    ArrayList<PartitionRequestInfo> partitionRequestInfoList = new ArrayList<PartitionRequestInfo>();
    partitionRequestInfoList.add(partitionRequestInfo);
    GetRequest getRequest = new GetRequest(1234, "clientId", MessageFormatFlags.Blob, partitionRequestInfoList, GetOption.None);
    RequestInfo requestInfo = new RequestInfo(hostname, port, getRequest, replica, null);
    ResponseInfo responseInfo = sendAndWaitForResponses(requestInfo);
    GetResponse response = responseInfo.getError() == null ? (GetResponse) RouterUtils.mapToReceivedResponse((Response) responseInfo.getResponse()) : null;
    PartitionResponseInfo partitionResponseInfo = response.getPartitionResponseInfoList().get(0);
    Assert.assertEquals("GetRequest should succeed.", response.getError(), ServerErrorCode.No_Error);
    Assert.assertEquals("GetRequest partitionResponseInfo should succeed.", partitionResponseInfo.getErrorCode(), ServerErrorCode.No_Error);
    responseInfo.release();
    // inject error for cloud colo.
    cloudDestination.setServerErrorForAllRequests(StoreErrorCodes.ID_Not_Found);
    getRequest = new GetRequest(1234, "clientId", MessageFormatFlags.Blob, partitionRequestInfoList, GetOption.None);
    requestInfo = new RequestInfo(hostname, port, getRequest, replica, null);
    responseInfo = sendAndWaitForResponses(requestInfo);
    response = responseInfo.getError() == null ? (GetResponse) RouterUtils.mapToReceivedResponse((Response) responseInfo.getResponse()) : null;
    partitionResponseInfo = response.getPartitionResponseInfoList().get(0);
    Assert.assertEquals("GetRequest responseInfo should have no error.", response.getError(), ServerErrorCode.No_Error);
    Assert.assertEquals("GetRequest partitionResponseInfo should be Blob_Not_Found", partitionResponseInfo.getErrorCode(), ServerErrorCode.Blob_Not_Found);
    responseInfo.release();
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) PartitionResponseInfo(com.github.ambry.protocol.PartitionResponseInfo) GetResponse(com.github.ambry.protocol.GetResponse) TtlUpdateResponse(com.github.ambry.protocol.TtlUpdateResponse) UndeleteResponse(com.github.ambry.protocol.UndeleteResponse) DeleteResponse(com.github.ambry.protocol.DeleteResponse) PutResponse(com.github.ambry.protocol.PutResponse) Response(com.github.ambry.protocol.Response) GetRequest(com.github.ambry.protocol.GetRequest) ArrayList(java.util.ArrayList) PartitionResponseInfo(com.github.ambry.protocol.PartitionResponseInfo) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) RequestInfo(com.github.ambry.network.RequestInfo) BlobId(com.github.ambry.commons.BlobId) GetResponse(com.github.ambry.protocol.GetResponse) Test(org.junit.Test)

Example 33 with GetResponse

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

the class ReplicaThread method fixMissingStoreKeys.

/**
 * Gets all the messages from the remote node for the missing keys and writes them to the local store
 * @param connectedChannel The connected channel that represents a connection to the remote replica
 * @param replicasToReplicatePerNode The information about the replicas that is being replicated
 * @param exchangeMetadataResponseList The missing keys in the local stores whose message needs to be retrieved
 *                                     from the remote stores
 * @param remoteColoGetRequestForStandby boolean which indicates if we are getting missing keys for standby or
 *                                       non-leader replica pairs during leader-based replication.
 * @throws IOException
 * @throws ReplicationException
 */
void fixMissingStoreKeys(ConnectedChannel connectedChannel, List<RemoteReplicaInfo> replicasToReplicatePerNode, List<ExchangeMetadataResponse> exchangeMetadataResponseList, boolean remoteColoGetRequestForStandby) throws IOException, ReplicationException {
    long fixMissingStoreKeysStartTimeInMs = time.milliseconds();
    GetResponse getResponse = null;
    try {
        if (exchangeMetadataResponseList.size() != replicasToReplicatePerNode.size() || replicasToReplicatePerNode.size() == 0) {
            throw new IllegalArgumentException("ExchangeMetadataResponseList size " + exchangeMetadataResponseList.size() + " and replicasToReplicatePerNode size " + replicasToReplicatePerNode.size() + " should be the same and greater than zero");
        }
        DataNodeId remoteNode = replicasToReplicatePerNode.get(0).getReplicaId().getDataNodeId();
        getResponse = getMessagesForMissingKeys(connectedChannel, exchangeMetadataResponseList, replicasToReplicatePerNode, remoteNode, remoteColoGetRequestForStandby);
        writeMessagesToLocalStoreAndAdvanceTokens(exchangeMetadataResponseList, getResponse, replicasToReplicatePerNode, remoteNode, remoteColoGetRequestForStandby);
    } finally {
        if (getResponse != null && getResponse.getInputStream() instanceof NettyByteBufDataInputStream) {
            // if the InputStream is NettyByteBufDataInputStream based, it's time to release its buffer.
            ((NettyByteBufDataInputStream) (getResponse.getInputStream())).getBuffer().release();
        }
        long fixMissingStoreKeysTime = time.milliseconds() - fixMissingStoreKeysStartTimeInMs;
        replicationMetrics.updateFixMissingStoreKeysTime(fixMissingStoreKeysTime, replicatingFromRemoteColo, replicatingOverSsl, datacenterName);
    }
}
Also used : NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) GetResponse(com.github.ambry.protocol.GetResponse) DataNodeId(com.github.ambry.clustermap.DataNodeId)

Example 34 with GetResponse

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

the class GetBlobResultInternal method handleResponse.

/**
 * Hands over the response to the associated GetOperation that issued the request.
 * @param responseInfo the {@link ResponseInfo} containing the response.
 */
void handleResponse(ResponseInfo responseInfo) {
    long startTime = time.milliseconds();
    GetResponse getResponse = RouterUtils.extractResponseAndNotifyResponseHandler(responseHandler, routerMetrics, responseInfo, stream -> GetResponse.readFrom(stream, clusterMap), response -> {
        ServerErrorCode serverError = response.getError();
        if (serverError == ServerErrorCode.No_Error) {
            serverError = response.getPartitionResponseInfoList().get(0).getErrorCode();
        }
        return serverError;
    });
    RequestInfo routerRequestInfo = responseInfo.getRequestInfo();
    GetRequest getRequest = (GetRequest) routerRequestInfo.getRequest();
    GetOperation getOperation = correlationIdToGetOperation.remove(getRequest.getCorrelationId());
    if (getOperation != null && getOperations.contains(getOperation)) {
        try {
            getOperation.handleResponse(responseInfo, getResponse);
            if (getOperation.isOperationComplete()) {
                remove(getOperation);
            }
        } catch (Exception e) {
            removeAndAbort(getOperation, new RouterException("Get handleResponse encountered unexpected error", e, RouterErrorCode.UnexpectedInternalError));
        }
        routerMetrics.getManagerHandleResponseTimeMs.update(time.milliseconds() - startTime);
    } else {
        routerMetrics.ignoredResponseCount.inc();
    }
}
Also used : GetRequest(com.github.ambry.protocol.GetRequest) RequestInfo(com.github.ambry.network.RequestInfo) GetResponse(com.github.ambry.protocol.GetResponse) ServerErrorCode(com.github.ambry.server.ServerErrorCode) IOException(java.io.IOException)

Example 35 with GetResponse

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

the class CloudOperationTest method getBlobAndAssertSuccess.

/**
 * Construct GetBlob operations with appropriate callbacks, then poll those operations until they complete,
 * and ensure that the whole blob data is read out and the contents match.
 * @param blobId id of the blob to get
 * @param expectedLifeVersion the expected lifeVersion from get operation.
 * @param expectedBlobSize the expected blob size
 * @param expectedBlobProperties  the expected {@link BlobProperties} for the blob.
 * @param expectedUserMetadata the expected user meta data
 * @param expectPutContent the expected blob content
 * @param options options of the get blob operation
 * @throws Exception Any unexpected exception
 */
private void getBlobAndAssertSuccess(final BlobId blobId, final short expectedLifeVersion, final int expectedBlobSize, final BlobProperties expectedBlobProperties, final byte[] expectedUserMetadata, final byte[] expectPutContent, final GetBlobOptionsInternal options) throws Exception {
    final CountDownLatch readCompleteLatch = new CountDownLatch(1);
    final AtomicLong readCompleteResult = new AtomicLong(0);
    // callback to compare the data
    Callback<GetBlobResultInternal> callback = (result, exception) -> {
        Assert.assertNull("Shouldn't have exception", exception);
        try {
            BlobInfo blobInfo;
            switch(options.getBlobOptions.getOperationType()) {
                case All:
                    Assert.assertFalse("not supposed to be raw mode", options.getBlobOptions.isRawMode());
                    blobInfo = result.getBlobResult.getBlobInfo();
                    Assert.assertTrue("Blob properties must be the same", RouterTestHelpers.arePersistedFieldsEquivalent(expectedBlobProperties, blobInfo.getBlobProperties()));
                    Assert.assertEquals("Blob size should in received blobProperties should be the same as actual", expectedBlobSize, blobInfo.getBlobProperties().getBlobSize());
                    Assert.assertArrayEquals("User metadata must be the same", expectedUserMetadata, blobInfo.getUserMetadata());
                    Assert.assertEquals("LifeVersion mismatch", expectedLifeVersion, blobInfo.getLifeVersion());
                    break;
                case Data:
                    Assert.assertNull("Unexpected blob info in operation result", result.getBlobResult.getBlobInfo());
                    break;
                case BlobInfo:
                    blobInfo = result.getBlobResult.getBlobInfo();
                    Assert.assertTrue("Blob properties must be the same", RouterTestHelpers.arePersistedFieldsEquivalent(expectedBlobProperties, blobInfo.getBlobProperties()));
                    Assert.assertEquals("Blob size should in received blobProperties should be the same as actual", expectedBlobSize, blobInfo.getBlobProperties().getBlobSize());
                    Assert.assertNull("Unexpected blob data in operation result", result.getBlobResult.getBlobDataChannel());
                    Assert.assertEquals("LifeVersion mismatch", expectedLifeVersion, blobInfo.getLifeVersion());
            }
        } catch (Throwable e) {
            Assert.fail("Shouldn't receive exception here");
        }
        if (options.getBlobOptions.getOperationType() != GetBlobOptions.OperationType.BlobInfo) {
            final ByteBufferAsyncWritableChannel asyncWritableChannel = new ByteBufferAsyncWritableChannel();
            Utils.newThread(() -> {
                Future<Long> readIntoFuture = result.getBlobResult.getBlobDataChannel().readInto(asyncWritableChannel, null);
                assertBlobReadSuccess(options.getBlobOptions, readIntoFuture, asyncWritableChannel, result.getBlobResult.getBlobDataChannel(), readCompleteLatch, readCompleteResult, expectedBlobSize, expectPutContent);
            }, false).start();
        } else {
            readCompleteLatch.countDown();
        }
    };
    // create GetBlobOperation
    final Map<Integer, GetOperation> correlationIdToGetOperation = new HashMap<>();
    final RequestRegistrationCallback<GetOperation> requestRegistrationCallback = new RequestRegistrationCallback<>(correlationIdToGetOperation);
    NonBlockingRouter.currentOperationsCount.incrementAndGet();
    GetBlobOperation op = new GetBlobOperation(routerConfig, routerMetrics, mockClusterMap, responseHandler, blobId, options, callback, routerCallback, blobIdFactory, null, null, null, time, false, null);
    requestRegistrationCallback.setRequestsToSend(new ArrayList<>());
    // Wait operation to complete
    while (!op.isOperationComplete()) {
        op.poll(requestRegistrationCallback);
        List<ResponseInfo> responses = sendAndWaitForResponses(requestRegistrationCallback.getRequestsToSend());
        for (ResponseInfo responseInfo : responses) {
            GetResponse getResponse = RouterUtils.extractResponseAndNotifyResponseHandler(responseHandler, routerMetrics, responseInfo, stream -> GetResponse.readFrom(stream, mockClusterMap), response -> {
                ServerErrorCode serverError = response.getError();
                if (serverError == ServerErrorCode.No_Error) {
                    serverError = response.getPartitionResponseInfoList().get(0).getErrorCode();
                }
                return serverError;
            });
            op.handleResponse(responseInfo, getResponse);
            responseInfo.release();
        }
    }
    readCompleteLatch.await();
    Assert.assertTrue("Operation should be complete at this time", op.isOperationComplete());
    // Ensure that a ChannelClosed exception is not set when the ReadableStreamChannel is closed correctly.
    Assert.assertNull("Callback operation exception should be null", op.getOperationException());
    if (options.getBlobOptions.getOperationType() != GetBlobOptions.OperationType.BlobInfo && !options.getBlobOptions.isRawMode() && !options.getChunkIdsOnly) {
        int sizeWritten = expectedBlobSize;
        if (options.getBlobOptions.getRange() != null) {
            ByteRange range = options.getBlobOptions.getRange().toResolvedByteRange(expectedBlobSize, options.getBlobOptions.resolveRangeOnEmptyBlob());
            sizeWritten = (int) range.getRangeSize();
        }
        Assert.assertEquals("Size read must equal size written", sizeWritten, readCompleteResult.get());
    }
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) Arrays(java.util.Arrays) BlobProperties(com.github.ambry.messageformat.BlobProperties) LocalNetworkClientFactory(com.github.ambry.network.LocalNetworkClientFactory) Random(java.util.Random) StoreErrorCodes(com.github.ambry.store.StoreErrorCodes) ByteBuffer(java.nio.ByteBuffer) GetResponse(com.github.ambry.protocol.GetResponse) Future(java.util.concurrent.Future) PortType(com.github.ambry.network.PortType) Map(java.util.Map) After(org.junit.After) NetworkConfig(com.github.ambry.config.NetworkConfig) NettyByteBufLeakHelper(com.github.ambry.utils.NettyByteBufLeakHelper) Parameterized(org.junit.runners.Parameterized) EnumMap(java.util.EnumMap) Collection(java.util.Collection) Utils(com.github.ambry.utils.Utils) PooledByteBufAllocator(io.netty.buffer.PooledByteBufAllocator) Collectors(java.util.stream.Collectors) BlobInfo(com.github.ambry.messageformat.BlobInfo) RouterConfig(com.github.ambry.config.RouterConfig) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) MockTime(com.github.ambry.utils.MockTime) LoggingNotificationSystem(com.github.ambry.commons.LoggingNotificationSystem) Callback(com.github.ambry.commons.Callback) BlobType(com.github.ambry.messageformat.BlobType) InMemAccountService(com.github.ambry.account.InMemAccountService) PartitionId(com.github.ambry.clustermap.PartitionId) BlobId(com.github.ambry.commons.BlobId) ResponseHandler(com.github.ambry.commons.ResponseHandler) NetworkMetrics(com.github.ambry.network.NetworkMetrics) DataInputStream(java.io.DataInputStream) CloudDestinationFactory(com.github.ambry.cloud.CloudDestinationFactory) ServerErrorCode(com.github.ambry.server.ServerErrorCode) RunWith(org.junit.runner.RunWith) AccountService(com.github.ambry.account.AccountService) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) CloudConfig(com.github.ambry.config.CloudConfig) NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) RequestHandlerPool(com.github.ambry.protocol.RequestHandlerPool) ByteBuf(io.netty.buffer.ByteBuf) LatchBasedInMemoryCloudDestination(com.github.ambry.cloud.LatchBasedInMemoryCloudDestination) LocalRequestResponseChannel(com.github.ambry.network.LocalRequestResponseChannel) PutRequest(com.github.ambry.protocol.PutRequest) NetworkClientFactory(com.github.ambry.network.NetworkClientFactory) Before(org.junit.Before) Properties(java.util.Properties) Iterator(java.util.Iterator) ReplicaType(com.github.ambry.clustermap.ReplicaType) NetworkClient(com.github.ambry.network.NetworkClient) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ByteBufferAsyncWritableChannel(com.github.ambry.commons.ByteBufferAsyncWritableChannel) Test(org.junit.Test) BlobIdFactory(com.github.ambry.commons.BlobIdFactory) LatchBasedInMemoryCloudDestinationFactory(com.github.ambry.cloud.LatchBasedInMemoryCloudDestinationFactory) RequestInfo(com.github.ambry.network.RequestInfo) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) CompositeNetworkClientFactory(com.github.ambry.network.CompositeNetworkClientFactory) ReplicaId(com.github.ambry.clustermap.ReplicaId) Port(com.github.ambry.network.Port) Assert(org.junit.Assert) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) ResponseInfo(com.github.ambry.network.ResponseInfo) HashMap(java.util.HashMap) BlobInfo(com.github.ambry.messageformat.BlobInfo) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBufferAsyncWritableChannel(com.github.ambry.commons.ByteBufferAsyncWritableChannel) GetResponse(com.github.ambry.protocol.GetResponse) ServerErrorCode(com.github.ambry.server.ServerErrorCode) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicLong(java.util.concurrent.atomic.AtomicLong)

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