Search in sources :

Example 1 with ChunkInfo

use of com.github.ambry.router.ChunkInfo in project ambry by linkedin.

the class PostBlobHandlerTest method stitchedUploadTest.

/**
 * Test flows related to the {@link Operations#STITCH} operation.
 * @throws Exception
 */
@Test
public void stitchedUploadTest() throws Exception {
    idConverterFactory.translation = CONVERTED_ID;
    String uploadSession = UUID.randomUUID().toString();
    long creationTimeMs = System.currentTimeMillis();
    time.setCurrentMilliseconds(creationTimeMs);
    String[] prefixToTest = new String[] { "/" + CLUSTER_NAME, "" };
    for (String prefix : prefixToTest) {
        // success cases
        // multiple chunks
        List<ChunkInfo> chunksToStitch = uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 45, 10, 200, 19, 0, 50);
        List<String> signedChunkIds = chunksToStitch.stream().map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), chunksToStitch, null);
        // one chunk
        chunksToStitch = uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 45);
        signedChunkIds = chunksToStitch.stream().map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), chunksToStitch, null);
        // failure cases
        // invalid json input
        stitchBlobAndVerify("badjsonbadjson".getBytes(StandardCharsets.UTF_8), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // no chunk ids in request
        stitchBlobAndVerify(getStitchRequestBody(Collections.emptyList()), null, restServiceExceptionChecker(RestServiceErrorCode.MissingArgs));
        stitchBlobAndVerify(new JSONObject().toString().getBytes(StandardCharsets.UTF_8), null, restServiceExceptionChecker(RestServiceErrorCode.MissingArgs));
        // differing session IDs
        signedChunkIds = uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 45, 22).stream().map(chunkInfo -> prefix + getSignedId(chunkInfo, UUID.randomUUID().toString())).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // differing containers
        signedChunkIds = Stream.concat(uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 50, 50).stream(), uploadChunksViaRouter(creationTimeMs, REF_CONTAINER_WITH_TTL_REQUIRED, 50).stream()).map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // differing accounts
        Container altAccountContainer = ACCOUNT_SERVICE.createAndAddRandomAccount().getContainerById(Container.DEFAULT_PRIVATE_CONTAINER_ID);
        signedChunkIds = Stream.concat(uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 50, 50).stream(), uploadChunksViaRouter(creationTimeMs, altAccountContainer, 50).stream()).map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // invalid blob ID
        stitchBlobAndVerify(getStitchRequestBody(Collections.singletonList(getSignedId(new ChunkInfo("abcd", 200, -1), uploadSession))), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // unsigned ID
        stitchBlobAndVerify(getStitchRequestBody(Collections.singletonList("/notASignedId")), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
    }
}
Also used : Arrays(java.util.Arrays) FrontendConfig(com.github.ambry.config.FrontendConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) URISyntaxException(java.net.URISyntaxException) FutureResult(com.github.ambry.router.FutureResult) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) ContainerBuilder(com.github.ambry.account.ContainerBuilder) ByteBuffer(java.nio.ByteBuffer) ThrowingConsumer(com.github.ambry.utils.ThrowingConsumer) JSONObject(org.json.JSONObject) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) ChunkInfo(com.github.ambry.router.ChunkInfo) RouterErrorCode(com.github.ambry.router.RouterErrorCode) Container(com.github.ambry.account.Container) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) Utils(com.github.ambry.utils.Utils) UUID(java.util.UUID) AccountBuilder(com.github.ambry.account.AccountBuilder) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) List(java.util.List) RestServiceException(com.github.ambry.rest.RestServiceException) Stream(java.util.stream.Stream) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) MockTime(com.github.ambry.utils.MockTime) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Account(com.github.ambry.account.Account) RestUtils(com.github.ambry.rest.RestUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InMemAccountService(com.github.ambry.account.InMemAccountService) InMemoryRouter(com.github.ambry.router.InMemoryRouter) ByteArrayOutputStream(java.io.ByteArrayOutputStream) AccountService(com.github.ambry.account.AccountService) HashMap(java.util.HashMap) QuotaManager(com.github.ambry.quota.QuotaManager) ArrayList(java.util.ArrayList) QuotaConfig(com.github.ambry.config.QuotaConfig) RequestPath(com.github.ambry.rest.RequestPath) QuotaMode(com.github.ambry.quota.QuotaMode) LinkedList(java.util.LinkedList) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) RestMethod(com.github.ambry.rest.RestMethod) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ClusterMap(com.github.ambry.clustermap.ClusterMap) Test(org.junit.Test) RouterException(com.github.ambry.router.RouterException) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AmbryQuotaManager(com.github.ambry.quota.AmbryQuotaManager) Mockito(org.mockito.Mockito) QuotaMetrics(com.github.ambry.quota.QuotaMetrics) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) SimpleQuotaRecommendationMergePolicy(com.github.ambry.quota.SimpleQuotaRecommendationMergePolicy) Assert(org.junit.Assert) RestRequest(com.github.ambry.rest.RestRequest) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Container(com.github.ambry.account.Container) ChunkInfo(com.github.ambry.router.ChunkInfo) JSONObject(org.json.JSONObject) Test(org.junit.Test)

Example 2 with ChunkInfo

use of com.github.ambry.router.ChunkInfo in project ambry by linkedin.

the class PostBlobHandlerTest method stitchBlobAndVerify.

/**
 * Make a stitch blob call using {@link PostBlobHandler} and verify the result of the operation.
 * @param requestBody the body of the stitch request to supply.
 * @param expectedStitchedChunks the expected chunks stitched together.
 * @param errorChecker if non-null, expect an exception to be thrown by the post flow and verify it using this
 *                     {@link ThrowingConsumer}.
 * @throws Exception
 */
private void stitchBlobAndVerify(byte[] requestBody, List<ChunkInfo> expectedStitchedChunks, ThrowingConsumer<ExecutionException> errorChecker) throws Exception {
    JSONObject headers = new JSONObject();
    FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, TestUtils.TTL_SECS, !REF_CONTAINER.isCacheable(), SERVICE_ID, CONTENT_TYPE, OWNER_ID, REF_ACCOUNT.getName(), REF_CONTAINER.getName(), null);
    RestRequest request = getRestRequest(headers, "/" + Operations.STITCH, requestBody);
    RestResponseChannel restResponseChannel = new MockRestResponseChannel();
    FutureResult<Void> future = new FutureResult<>();
    idConverterFactory.lastInput = null;
    postBlobHandler.handle(request, restResponseChannel, future::done);
    if (errorChecker == null) {
        future.get(TIMEOUT_SECS, TimeUnit.SECONDS);
        assertEquals("Unexpected converted ID", CONVERTED_ID, restResponseChannel.getHeader(RestUtils.Headers.LOCATION));
        InMemoryRouter.InMemoryBlob blob = router.getActiveBlobs().get(idConverterFactory.lastInput);
        assertEquals("List of chunks stitched does not match expected", expectedStitchedChunks, blob.getStitchedChunks());
        ByteArrayOutputStream expectedContent = new ByteArrayOutputStream();
        expectedStitchedChunks.stream().map(chunkInfo -> router.getActiveBlobs().get(chunkInfo.getBlobId()).getBlob().array()).forEach(buf -> expectedContent.write(buf, 0, buf.length));
        assertEquals("Unexpected blob content stored", ByteBuffer.wrap(expectedContent.toByteArray()), blob.getBlob());
        // check actual size of stitched blob
        assertEquals("Unexpected blob size", Long.toString(getStitchedBlobSize(expectedStitchedChunks)), restResponseChannel.getHeader(RestUtils.Headers.BLOB_SIZE));
    } else {
        TestUtils.assertException(ExecutionException.class, () -> future.get(TIMEOUT_SECS, TimeUnit.SECONDS), errorChecker);
    }
}
Also used : Arrays(java.util.Arrays) FrontendConfig(com.github.ambry.config.FrontendConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) URISyntaxException(java.net.URISyntaxException) FutureResult(com.github.ambry.router.FutureResult) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) ContainerBuilder(com.github.ambry.account.ContainerBuilder) ByteBuffer(java.nio.ByteBuffer) ThrowingConsumer(com.github.ambry.utils.ThrowingConsumer) JSONObject(org.json.JSONObject) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) ChunkInfo(com.github.ambry.router.ChunkInfo) RouterErrorCode(com.github.ambry.router.RouterErrorCode) Container(com.github.ambry.account.Container) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) Utils(com.github.ambry.utils.Utils) UUID(java.util.UUID) AccountBuilder(com.github.ambry.account.AccountBuilder) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) List(java.util.List) RestServiceException(com.github.ambry.rest.RestServiceException) Stream(java.util.stream.Stream) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) MockTime(com.github.ambry.utils.MockTime) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Account(com.github.ambry.account.Account) RestUtils(com.github.ambry.rest.RestUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InMemAccountService(com.github.ambry.account.InMemAccountService) InMemoryRouter(com.github.ambry.router.InMemoryRouter) ByteArrayOutputStream(java.io.ByteArrayOutputStream) AccountService(com.github.ambry.account.AccountService) HashMap(java.util.HashMap) QuotaManager(com.github.ambry.quota.QuotaManager) ArrayList(java.util.ArrayList) QuotaConfig(com.github.ambry.config.QuotaConfig) RequestPath(com.github.ambry.rest.RequestPath) QuotaMode(com.github.ambry.quota.QuotaMode) LinkedList(java.util.LinkedList) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) RestMethod(com.github.ambry.rest.RestMethod) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ClusterMap(com.github.ambry.clustermap.ClusterMap) Test(org.junit.Test) RouterException(com.github.ambry.router.RouterException) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AmbryQuotaManager(com.github.ambry.quota.AmbryQuotaManager) Mockito(org.mockito.Mockito) QuotaMetrics(com.github.ambry.quota.QuotaMetrics) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) SimpleQuotaRecommendationMergePolicy(com.github.ambry.quota.SimpleQuotaRecommendationMergePolicy) Assert(org.junit.Assert) RestRequest(com.github.ambry.rest.RestRequest) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) InMemoryRouter(com.github.ambry.router.InMemoryRouter) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) FutureResult(com.github.ambry.router.FutureResult) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) ByteArrayOutputStream(java.io.ByteArrayOutputStream) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel)

Example 3 with ChunkInfo

use of com.github.ambry.router.ChunkInfo in project ambry by linkedin.

the class NamedBlobPutHandlerTest method stitchBlobAndVerify.

/**
 * Make a stitch blob call using {@link PostBlobHandler} and verify the result of the operation.
 * @param requestBody the body of the stitch request to supply.
 * @param expectedStitchedChunks the expected chunks stitched together.
 * @param errorChecker if non-null, expect an exception to be thrown by the post flow and verify it using this
 *                     {@link ThrowingConsumer}.
 * @throws Exception
 */
private void stitchBlobAndVerify(byte[] requestBody, List<ChunkInfo> expectedStitchedChunks, ThrowingConsumer<ExecutionException> errorChecker) throws Exception {
    // call
    for (long ttl : new long[] { TestUtils.TTL_SECS, Utils.Infinite_Time }) {
        JSONObject headers = new JSONObject();
        FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, ttl, !REF_CONTAINER.isCacheable(), SERVICE_ID, CONTENT_TYPE, OWNER_ID, null, null, "STITCH");
        RestRequest request = getRestRequest(headers, request_path, requestBody);
        RestResponseChannel restResponseChannel = new MockRestResponseChannel();
        FutureResult<Void> future = new FutureResult<>();
        idConverterFactory.lastInput = null;
        idConverterFactory.lastBlobInfo = null;
        idConverterFactory.lastConvertedId = null;
        namedBlobPutHandler.handle(request, restResponseChannel, future::done);
        if (errorChecker == null) {
            future.get(TIMEOUT_SECS, TimeUnit.SECONDS);
            assertEquals("Unexpected location header", idConverterFactory.lastConvertedId, restResponseChannel.getHeader(RestUtils.Headers.LOCATION));
            InMemoryRouter.InMemoryBlob blob = router.getActiveBlobs().get(idConverterFactory.lastInput);
            assertEquals("List of chunks stitched does not match expected", expectedStitchedChunks, blob.getStitchedChunks());
            ByteArrayOutputStream expectedContent = new ByteArrayOutputStream();
            expectedStitchedChunks.stream().map(chunkInfo -> router.getActiveBlobs().get(chunkInfo.getBlobId()).getBlob().array()).forEach(buf -> expectedContent.write(buf, 0, buf.length));
            assertEquals("Unexpected blob content stored", ByteBuffer.wrap(expectedContent.toByteArray()), blob.getBlob());
            // check actual size of stitched blob
            assertEquals("Unexpected blob size", Long.toString(getStitchedBlobSize(expectedStitchedChunks)), restResponseChannel.getHeader(RestUtils.Headers.BLOB_SIZE));
            assertEquals("Unexpected TTL in named blob DB", ttl, idConverterFactory.lastBlobInfo.getBlobProperties().getTimeToLiveInSeconds());
            assertEquals("Unexpected TTL in blob", ttl, blob.getBlobProperties().getTimeToLiveInSeconds());
        } else {
            TestUtils.assertException(ExecutionException.class, () -> future.get(TIMEOUT_SECS, TimeUnit.SECONDS), errorChecker);
        }
    }
}
Also used : Arrays(java.util.Arrays) FrontendConfig(com.github.ambry.config.FrontendConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) URISyntaxException(java.net.URISyntaxException) ResponseStatus(com.github.ambry.rest.ResponseStatus) FutureResult(com.github.ambry.router.FutureResult) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) ContainerBuilder(com.github.ambry.account.ContainerBuilder) ByteBuffer(java.nio.ByteBuffer) ThrowingConsumer(com.github.ambry.utils.ThrowingConsumer) JSONObject(org.json.JSONObject) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) ChunkInfo(com.github.ambry.router.ChunkInfo) Container(com.github.ambry.account.Container) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) Utils(com.github.ambry.utils.Utils) UUID(java.util.UUID) AccountBuilder(com.github.ambry.account.AccountBuilder) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) List(java.util.List) RestServiceException(com.github.ambry.rest.RestServiceException) Stream(java.util.stream.Stream) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) MockTime(com.github.ambry.utils.MockTime) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Account(com.github.ambry.account.Account) RestUtils(com.github.ambry.rest.RestUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InMemAccountService(com.github.ambry.account.InMemAccountService) InMemoryRouter(com.github.ambry.router.InMemoryRouter) ByteArrayOutputStream(java.io.ByteArrayOutputStream) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RequestPath(com.github.ambry.rest.RequestPath) LinkedList(java.util.LinkedList) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) RestMethod(com.github.ambry.rest.RestMethod) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ClusterMap(com.github.ambry.clustermap.ClusterMap) Test(org.junit.Test) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) Assert(org.junit.Assert) RestRequest(com.github.ambry.rest.RestRequest) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) ByteArrayOutputStream(java.io.ByteArrayOutputStream) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) InMemoryRouter(com.github.ambry.router.InMemoryRouter) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) FutureResult(com.github.ambry.router.FutureResult) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel)

Example 4 with ChunkInfo

use of com.github.ambry.router.ChunkInfo in project ambry by linkedin.

the class NamedBlobPutHandlerTest method uploadChunksViaRouter.

/**
 * 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 5 with ChunkInfo

use of com.github.ambry.router.ChunkInfo in project ambry by linkedin.

the class NamedBlobPutHandlerTest method stitchNamedBlobTest.

/**
 * Test flows related to the stitch named blob operation.
 * @throws Exception
 */
@Test
public void stitchNamedBlobTest() throws Exception {
    idConverterFactory.translation = CONVERTED_ID;
    long creationTimeMs = System.currentTimeMillis();
    time.setCurrentMilliseconds(creationTimeMs);
    // success case
    String uploadSession = UUID.randomUUID().toString();
    String[] prefixToTest = new String[] { "/" + CLUSTER_NAME, "" };
    for (String prefix : prefixToTest) {
        // multiple chunks
        List<ChunkInfo> chunksToStitch = uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 45, 10, 200, 19, 0, 50);
        List<String> signedChunkIds = chunksToStitch.stream().map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), chunksToStitch, null);
        // one chunk
        chunksToStitch = uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 45);
        signedChunkIds = chunksToStitch.stream().map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), chunksToStitch, null);
        // failure cases
        // invalid json input
        stitchBlobAndVerify("badjsonbadjson".getBytes(StandardCharsets.UTF_8), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // no chunk ids in request
        stitchBlobAndVerify(getStitchRequestBody(Collections.emptyList()), null, restServiceExceptionChecker(RestServiceErrorCode.MissingArgs));
        stitchBlobAndVerify(new JSONObject().toString().getBytes(StandardCharsets.UTF_8), null, restServiceExceptionChecker(RestServiceErrorCode.MissingArgs));
        // differing session IDs
        signedChunkIds = uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 45, 22).stream().map(chunkInfo -> prefix + getSignedId(chunkInfo, UUID.randomUUID().toString())).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // differing containers
        signedChunkIds = Stream.concat(uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 50, 50).stream(), uploadChunksViaRouter(creationTimeMs, REF_CONTAINER_WITH_TTL_REQUIRED, 50).stream()).map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // differing accounts
        Container altAccountContainer = ACCOUNT_SERVICE.createAndAddRandomAccount().getContainerById(Container.DEFAULT_PRIVATE_CONTAINER_ID);
        signedChunkIds = Stream.concat(uploadChunksViaRouter(creationTimeMs, REF_CONTAINER, 50, 50).stream(), uploadChunksViaRouter(creationTimeMs, altAccountContainer, 50).stream()).map(chunkInfo -> prefix + getSignedId(chunkInfo, uploadSession)).collect(Collectors.toList());
        stitchBlobAndVerify(getStitchRequestBody(signedChunkIds), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // invalid blob ID
        stitchBlobAndVerify(getStitchRequestBody(Collections.singletonList(getSignedId(new ChunkInfo("abcd", 200, -1), uploadSession))), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
        // unsigned ID
        stitchBlobAndVerify(getStitchRequestBody(Collections.singletonList("/notASignedId")), null, restServiceExceptionChecker(RestServiceErrorCode.BadRequest));
    }
}
Also used : Arrays(java.util.Arrays) FrontendConfig(com.github.ambry.config.FrontendConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) URISyntaxException(java.net.URISyntaxException) ResponseStatus(com.github.ambry.rest.ResponseStatus) FutureResult(com.github.ambry.router.FutureResult) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) ContainerBuilder(com.github.ambry.account.ContainerBuilder) ByteBuffer(java.nio.ByteBuffer) ThrowingConsumer(com.github.ambry.utils.ThrowingConsumer) JSONObject(org.json.JSONObject) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) ChunkInfo(com.github.ambry.router.ChunkInfo) Container(com.github.ambry.account.Container) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) Utils(com.github.ambry.utils.Utils) UUID(java.util.UUID) AccountBuilder(com.github.ambry.account.AccountBuilder) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) List(java.util.List) RestServiceException(com.github.ambry.rest.RestServiceException) Stream(java.util.stream.Stream) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) MockTime(com.github.ambry.utils.MockTime) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Account(com.github.ambry.account.Account) RestUtils(com.github.ambry.rest.RestUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InMemAccountService(com.github.ambry.account.InMemAccountService) InMemoryRouter(com.github.ambry.router.InMemoryRouter) ByteArrayOutputStream(java.io.ByteArrayOutputStream) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RequestPath(com.github.ambry.rest.RequestPath) LinkedList(java.util.LinkedList) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) RestMethod(com.github.ambry.rest.RestMethod) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ClusterMap(com.github.ambry.clustermap.ClusterMap) Test(org.junit.Test) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) Assert(org.junit.Assert) RestRequest(com.github.ambry.rest.RestRequest) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Container(com.github.ambry.account.Container) ChunkInfo(com.github.ambry.router.ChunkInfo) JSONObject(org.json.JSONObject) Test(org.junit.Test)

Aggregations

ByteBufferReadableStreamChannel (com.github.ambry.commons.ByteBufferReadableStreamChannel)6 BlobProperties (com.github.ambry.messageformat.BlobProperties)6 ChunkInfo (com.github.ambry.router.ChunkInfo)6 PutBlobOptionsBuilder (com.github.ambry.router.PutBlobOptionsBuilder)6 ArrayList (java.util.ArrayList)6 MetricRegistry (com.codahale.metrics.MetricRegistry)4 Account (com.github.ambry.account.Account)4 AccountBuilder (com.github.ambry.account.AccountBuilder)4 Container (com.github.ambry.account.Container)4 ContainerBuilder (com.github.ambry.account.ContainerBuilder)4 InMemAccountService (com.github.ambry.account.InMemAccountService)4 ClusterMap (com.github.ambry.clustermap.ClusterMap)4 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)4 FrontendConfig (com.github.ambry.config.FrontendConfig)4 VerifiableProperties (com.github.ambry.config.VerifiableProperties)4 QuotaTestUtils (com.github.ambry.quota.QuotaTestUtils)4 MockRestResponseChannel (com.github.ambry.rest.MockRestResponseChannel)4 RequestPath (com.github.ambry.rest.RequestPath)4 RestMethod (com.github.ambry.rest.RestMethod)4 RestRequest (com.github.ambry.rest.RestRequest)4