Search in sources :

Example 51 with BlobProperties

use of com.github.ambry.messageformat.BlobProperties in project ambry by linkedin.

the class PostBlobHandlerTest method uploadChunksViaRouter.

// stitchedUploadTest() helpers
/**
 * Upload chunks using the router directly.
 * @param creationTimeMs the creation time to set for the chunks.
 * @param container the {@link Container} to create the chunks in.
 * @param chunkSizes the sizes for each chunk to upload.
 * @return a list of {@link ChunkInfo} objects that contains metadata about each chunk uploaded.
 */
private List<ChunkInfo> uploadChunksViaRouter(long creationTimeMs, Container container, int... chunkSizes) throws Exception {
    long blobTtlSecs = TimeUnit.DAYS.toSeconds(1);
    List<ChunkInfo> chunks = new ArrayList<>();
    for (int chunkSize : chunkSizes) {
        byte[] content = TestUtils.getRandomBytes(chunkSize);
        BlobProperties blobProperties = new BlobProperties(-1, SERVICE_ID, OWNER_ID, CONTENT_TYPE, !container.isCacheable(), blobTtlSecs, creationTimeMs, container.getParentAccountId(), container.getId(), container.isEncrypted(), null, null, null);
        String blobId = router.putBlob(blobProperties, null, new ByteBufferReadableStreamChannel(ByteBuffer.wrap(content)), new PutBlobOptionsBuilder().chunkUpload(true).build()).get(TIMEOUT_SECS, TimeUnit.SECONDS);
        chunks.add(new ChunkInfo(blobId, chunkSize, Utils.addSecondsToEpochTime(creationTimeMs, blobTtlSecs)));
    }
    return chunks;
}
Also used : ChunkInfo(com.github.ambry.router.ChunkInfo) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) BlobProperties(com.github.ambry.messageformat.BlobProperties) ArrayList(java.util.ArrayList)

Example 52 with BlobProperties

use of com.github.ambry.messageformat.BlobProperties in project ambry by linkedin.

the class AmbryRequests method handlePutRequest.

@Override
public void handlePutRequest(NetworkRequest request) throws IOException, InterruptedException {
    PutRequest receivedRequest;
    if (request instanceof LocalChannelRequest) {
        // This is a case where handlePutRequest is called when frontends are writing to Azure. In this case, this method
        // is called by request handler threads running within the frontend router itself. So, the request can be directly
        // referenced as java objects without any need for deserialization.
        PutRequest sentRequest = (PutRequest) ((LocalChannelRequest) request).getRequestInfo().getRequest();
        // However, we will create a new PutRequest object to represent the received Put request since the blob content
        // 'buffer' in PutRequest is accessed as 'stream' while writing to Store. Also, crc value for this request
        // would be null since it is only calculated (on the fly) when sending the request to network. It might be okay to
        // use null crc here since the scenario for which we are using crc (i.e. possibility of collisions due to fast
        // replication) as described in this PR https://github.com/linkedin/ambry/pull/549 might not be applicable when
        // frontends are talking to Azure.
        receivedRequest = new PutRequest(sentRequest.getCorrelationId(), sentRequest.getClientId(), sentRequest.getBlobId(), sentRequest.getBlobProperties(), sentRequest.getUsermetadata(), sentRequest.getBlobSize(), sentRequest.getBlobType(), sentRequest.getBlobEncryptionKey(), new ByteBufInputStream(sentRequest.getBlob()), null);
    } else {
        InputStream is = request.getInputStream();
        DataInputStream dis = is instanceof DataInputStream ? (DataInputStream) is : new DataInputStream(is);
        receivedRequest = PutRequest.readFrom(dis, clusterMap);
    }
    long requestQueueTime = SystemTime.getInstance().milliseconds() - request.getStartTimeInMs();
    long totalTimeSpent = requestQueueTime;
    metrics.putBlobRequestQueueTimeInMs.update(requestQueueTime);
    metrics.putBlobRequestRate.mark();
    long startTime = SystemTime.getInstance().milliseconds();
    PutResponse response = null;
    try {
        ServerErrorCode error = validateRequest(receivedRequest.getBlobId().getPartition(), RequestOrResponseType.PutRequest, false);
        if (error != ServerErrorCode.No_Error) {
            logger.error("Validating put request failed with error {} for request {}", error, receivedRequest);
            response = new PutResponse(receivedRequest.getCorrelationId(), receivedRequest.getClientId(), error);
        } else {
            MessageFormatInputStream stream = new PutMessageFormatInputStream(receivedRequest.getBlobId(), receivedRequest.getBlobEncryptionKey(), receivedRequest.getBlobProperties(), receivedRequest.getUsermetadata(), receivedRequest.getBlobStream(), receivedRequest.getBlobSize(), receivedRequest.getBlobType());
            BlobProperties properties = receivedRequest.getBlobProperties();
            long expirationTime = Utils.addSecondsToEpochTime(receivedRequest.getBlobProperties().getCreationTimeInMs(), properties.getTimeToLiveInSeconds());
            MessageInfo info = new MessageInfo.Builder(receivedRequest.getBlobId(), stream.getSize(), properties.getAccountId(), properties.getContainerId(), properties.getCreationTimeInMs()).expirationTimeInMs(expirationTime).crc(receivedRequest.getCrc()).lifeVersion(MessageInfo.LIFE_VERSION_FROM_FRONTEND).build();
            ArrayList<MessageInfo> infoList = new ArrayList<>();
            infoList.add(info);
            MessageFormatWriteSet writeset = new MessageFormatWriteSet(stream, infoList, false);
            Store storeToPut = storeManager.getStore(receivedRequest.getBlobId().getPartition());
            storeToPut.put(writeset);
            response = new PutResponse(receivedRequest.getCorrelationId(), receivedRequest.getClientId(), ServerErrorCode.No_Error);
            metrics.blobSizeInBytes.update(receivedRequest.getBlobSize());
            metrics.blobUserMetadataSizeInBytes.update(receivedRequest.getUsermetadata().limit());
            if (notification != null) {
                notification.onBlobReplicaCreated(currentNode.getHostname(), currentNode.getPort(), receivedRequest.getBlobId().getID(), BlobReplicaSourceType.PRIMARY);
            }
        }
    } catch (StoreException e) {
        logger.error("Store exception on a put with error code {} for request {}", e.getErrorCode(), receivedRequest, e);
        if (e.getErrorCode() == StoreErrorCodes.Already_Exist) {
            metrics.idAlreadyExistError.inc();
        } else if (e.getErrorCode() == StoreErrorCodes.IOError) {
            metrics.storeIOError.inc();
        } else {
            metrics.unExpectedStorePutError.inc();
        }
        response = new PutResponse(receivedRequest.getCorrelationId(), receivedRequest.getClientId(), ErrorMapping.getStoreErrorMapping(e.getErrorCode()));
    } catch (Exception e) {
        logger.error("Unknown exception on a put for request {}", receivedRequest, e);
        response = new PutResponse(receivedRequest.getCorrelationId(), receivedRequest.getClientId(), ServerErrorCode.Unknown_Error);
    } finally {
        long processingTime = SystemTime.getInstance().milliseconds() - startTime;
        totalTimeSpent += processingTime;
        publicAccessLogger.info("{} {} processingTime {}", receivedRequest, response, processingTime);
        metrics.putBlobProcessingTimeInMs.update(processingTime);
        metrics.updatePutBlobProcessingTimeBySize(receivedRequest.getBlobSize(), processingTime);
    }
    sendPutResponse(requestResponseChannel, response, request, metrics.putBlobResponseQueueTimeInMs, metrics.putBlobSendTimeInMs, metrics.putBlobTotalTimeInMs, totalTimeSpent, receivedRequest.getBlobSize(), metrics);
}
Also used : MessageFormatInputStream(com.github.ambry.messageformat.MessageFormatInputStream) DataInputStream(java.io.DataInputStream) ByteBufInputStream(io.netty.buffer.ByteBufInputStream) PutMessageFormatInputStream(com.github.ambry.messageformat.PutMessageFormatInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) PutMessageFormatInputStream(com.github.ambry.messageformat.PutMessageFormatInputStream) Store(com.github.ambry.store.Store) ByteBufInputStream(io.netty.buffer.ByteBufInputStream) MessageFormatInputStream(com.github.ambry.messageformat.MessageFormatInputStream) PutMessageFormatInputStream(com.github.ambry.messageformat.PutMessageFormatInputStream) DataInputStream(java.io.DataInputStream) ServerErrorCode(com.github.ambry.server.ServerErrorCode) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) MessageInfo(com.github.ambry.store.MessageInfo) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) BlobProperties(com.github.ambry.messageformat.BlobProperties) LocalChannelRequest(com.github.ambry.network.LocalRequestResponseChannel.LocalChannelRequest) MessageFormatWriteSet(com.github.ambry.messageformat.MessageFormatWriteSet)

Example 53 with BlobProperties

use of com.github.ambry.messageformat.BlobProperties in project ambry by linkedin.

the class RequestResponseTest method putRequestResponseTest.

@Test
public void putRequestResponseTest() throws IOException {
    MockClusterMap clusterMap = new MockClusterMap();
    int correlationId = 5;
    String clientId = "client";
    BlobId blobId = new BlobId(CommonTestUtils.getCurrentBlobIdVersion(), BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, Utils.getRandomShort(TestUtils.RANDOM), Utils.getRandomShort(TestUtils.RANDOM), clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK);
    byte[] userMetadata = new byte[50];
    TestUtils.RANDOM.nextBytes(userMetadata);
    int blobKeyLength = TestUtils.RANDOM.nextInt(4096);
    byte[] blobKey = new byte[blobKeyLength];
    TestUtils.RANDOM.nextBytes(blobKey);
    int blobSize = 100;
    byte[] blob = new byte[blobSize];
    TestUtils.RANDOM.nextBytes(blob);
    BlobProperties blobProperties = new BlobProperties(blobSize, "serviceID", "memberId", "contentType", false, Utils.Infinite_Time, Utils.getRandomShort(TestUtils.RANDOM), Utils.getRandomShort(TestUtils.RANDOM), TestUtils.RANDOM.nextBoolean(), null, null, null);
    testPutRequest(clusterMap, correlationId, clientId, blobId, blobProperties, userMetadata, BlobType.DataBlob, blob, blobSize, blobKey);
    doPutRequestTest(InvalidVersionPutRequest.Put_Request_Invalid_version, clusterMap, correlationId, clientId, blobId, blobProperties, userMetadata, BlobType.DataBlob, blob, blobSize, blobKey, null);
    // Put Request with size in blob properties different from the data size and blob type: Data blob.
    blobProperties = new BlobProperties(blobSize * 10, "serviceID", "memberId", "contentType", false, Utils.Infinite_Time, Utils.getRandomShort(TestUtils.RANDOM), Utils.getRandomShort(TestUtils.RANDOM), TestUtils.RANDOM.nextBoolean(), null, null, null);
    testPutRequest(clusterMap, correlationId, clientId, blobId, blobProperties, userMetadata, BlobType.DataBlob, blob, blobSize, blobKey);
    // Put Request with size in blob properties different from the data size and blob type: Metadata blob.
    blobProperties = new BlobProperties(blobSize * 10, "serviceID", "memberId", "contentType", false, Utils.Infinite_Time, Utils.getRandomShort(TestUtils.RANDOM), Utils.getRandomShort(TestUtils.RANDOM), TestUtils.RANDOM.nextBoolean(), null, null, null);
    testPutRequest(clusterMap, correlationId, clientId, blobId, blobProperties, userMetadata, BlobType.MetadataBlob, blob, blobSize, blobKey);
    // Put Request with empty user metadata.
    byte[] emptyUserMetadata = new byte[0];
    blobProperties = new BlobProperties(blobSize, "serviceID", "memberId", "contentType", false, Utils.Infinite_Time, Utils.getRandomShort(TestUtils.RANDOM), Utils.getRandomShort(TestUtils.RANDOM), TestUtils.RANDOM.nextBoolean(), null, null, null);
    testPutRequest(clusterMap, correlationId, clientId, blobId, blobProperties, emptyUserMetadata, BlobType.DataBlob, blob, blobSize, blobKey);
    // Response test
    PutResponse response = new PutResponse(1234, clientId, ServerErrorCode.No_Error);
    DataInputStream responseStream = serAndPrepForRead(response, -1, false);
    PutResponse deserializedPutResponse = PutResponse.readFrom(responseStream);
    Assert.assertEquals(deserializedPutResponse.getCorrelationId(), 1234);
    Assert.assertEquals(deserializedPutResponse.getError(), ServerErrorCode.No_Error);
    response.release();
}
Also used : BlobProperties(com.github.ambry.messageformat.BlobProperties) DataInputStream(java.io.DataInputStream) NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) BlobId(com.github.ambry.commons.BlobId) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Example 54 with BlobProperties

use of com.github.ambry.messageformat.BlobProperties in project ambry by linkedin.

the class CloudOperationTest method doDirectPut.

/**
 * Do a put directly to the mock servers. This allows for blobs with malformed properties to be constructed.
 * @param blobProperties the {@link BlobProperties} for the blob.
 * @param userMetadata user meta data of the blob.
 * @param blobContent the raw content for the blob to upload (i.e. this can be serialized composite blob metadata or
 *                    an encrypted blob).
 * @return the blob id
 * @throws Exception Any unexpected exception
 */
private BlobId doDirectPut(BlobProperties blobProperties, byte[] userMetadata, ByteBuf blobContent) throws Exception {
    List<PartitionId> writablePartitionIds = mockClusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS);
    PartitionId partitionId = writablePartitionIds.get(random.nextInt(writablePartitionIds.size()));
    BlobId blobId = new BlobId(routerConfig.routerBlobidCurrentVersion, BlobId.BlobIdType.NATIVE, mockClusterMap.getLocalDatacenterId(), blobProperties.getAccountId(), blobProperties.getContainerId(), partitionId, blobProperties.isEncrypted(), BlobId.BlobDataType.DATACHUNK);
    Iterator<MockServer> servers = partitionId.getReplicaIds().stream().map(ReplicaId::getDataNodeId).map(dataNodeId -> mockServerLayout.getMockServer(dataNodeId.getHostname(), dataNodeId.getPort())).iterator();
    ByteBuffer userMetadataBuf = ByteBuffer.wrap(userMetadata);
    while (servers.hasNext()) {
        MockServer server = servers.next();
        PutRequest request = new PutRequest(random.nextInt(), "clientId", blobId, blobProperties, userMetadataBuf.duplicate(), blobContent.retainedDuplicate(), blobContent.readableBytes(), BlobType.DataBlob, null);
        // Make sure we release the BoundedNettyByteBufReceive.
        server.send(request).release();
        request.release();
    }
    // send to Cloud destinations.
    PutRequest request = new PutRequest(random.nextInt(), "clientId", blobId, blobProperties, userMetadataBuf.duplicate(), blobContent.retainedDuplicate(), blobContent.readableBytes(), BlobType.DataBlob, null);
    // Get the cloud replica.
    ReplicaId replica = partitionId.getReplicaIds().get(0);
    Assert.assertEquals("It should be a cloud backed replica.", replica.getReplicaType(), ReplicaType.CLOUD_BACKED);
    String hostname = replica.getDataNodeId().getHostname();
    Port port = new Port(-1, PortType.PLAINTEXT);
    List<RequestInfo> requestList = new ArrayList<>();
    RequestInfo requestInfo = new RequestInfo(hostname, port, request, replica, null);
    requestList.add(requestInfo);
    List<ResponseInfo> responseList = sendAndWaitForResponses(requestList);
    request.release();
    blobContent.release();
    return blobId;
}
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) Port(com.github.ambry.network.Port) ArrayList(java.util.ArrayList) PutRequest(com.github.ambry.protocol.PutRequest) PartitionId(com.github.ambry.clustermap.PartitionId) RequestInfo(com.github.ambry.network.RequestInfo) ByteBuffer(java.nio.ByteBuffer) ReplicaId(com.github.ambry.clustermap.ReplicaId) BlobId(com.github.ambry.commons.BlobId)

Example 55 with BlobProperties

use of com.github.ambry.messageformat.BlobProperties 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

BlobProperties (com.github.ambry.messageformat.BlobProperties)79 BlobId (com.github.ambry.commons.BlobId)35 ArrayList (java.util.ArrayList)35 DataInputStream (java.io.DataInputStream)26 Test (org.junit.Test)25 ByteBufferReadableStreamChannel (com.github.ambry.commons.ByteBufferReadableStreamChannel)24 VerifiableProperties (com.github.ambry.config.VerifiableProperties)24 ByteBuffer (java.nio.ByteBuffer)24 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)20 GetResponse (com.github.ambry.protocol.GetResponse)20 PutRequest (com.github.ambry.protocol.PutRequest)20 IOException (java.io.IOException)20 Properties (java.util.Properties)20 InMemAccountService (com.github.ambry.account.InMemAccountService)19 PartitionRequestInfo (com.github.ambry.protocol.PartitionRequestInfo)19 LoggingNotificationSystem (com.github.ambry.commons.LoggingNotificationSystem)18 ByteBuf (io.netty.buffer.ByteBuf)18 GetRequest (com.github.ambry.protocol.GetRequest)17 NettyByteBufDataInputStream (com.github.ambry.utils.NettyByteBufDataInputStream)17 CountDownLatch (java.util.concurrent.CountDownLatch)16