Search in sources :

Example 16 with ResponseParts

use of com.github.ambry.rest.NettyClient.ResponseParts in project ambry by linkedin.

the class FrontendIntegrationTest method getAndUseSignedUrlTest.

/**
 * Tests the handling of {@link Operations#GET_SIGNED_URL} requests.
 * @throws Exception
 */
@Test
public void getAndUseSignedUrlTest() throws Exception {
    Account account = ACCOUNT_SERVICE.createAndAddRandomAccount();
    Container container = account.getContainerById(Container.DEFAULT_PRIVATE_CONTAINER_ID);
    // setup
    ByteBuffer content = ByteBuffer.wrap(TestUtils.getRandomBytes(10));
    String serviceId = "getAndUseSignedUrlTest";
    String contentType = "application/octet-stream";
    String ownerId = "getAndUseSignedUrlTest";
    HttpHeaders headers = new DefaultHttpHeaders();
    headers.add(RestUtils.Headers.URL_TYPE, RestMethod.POST.name());
    setAmbryHeadersForPut(headers, TTL_SECS, !container.isCacheable(), serviceId, contentType, ownerId, account.getName(), container.getName());
    headers.add(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key1", "value1");
    headers.add(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key2", "value2");
    // POST
    // Get signed URL
    FullHttpRequest httpRequest = buildRequest(HttpMethod.GET, Operations.GET_SIGNED_URL, headers, null);
    ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    verifyTrackingHeaders(response);
    assertNotNull("There should be a response from the server", response);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    String signedPostUrl = response.headers().get(RestUtils.Headers.SIGNED_URL);
    assertNotNull("Did not get a signed POST URL", signedPostUrl);
    assertNoContent(responseParts.queue, 1);
    // Use signed URL to POST
    URI uri = new URI(signedPostUrl);
    httpRequest = buildRequest(HttpMethod.POST, uri.getPath() + "?" + uri.getQuery(), null, content);
    responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    String blobId = verifyPostAndReturnBlobId(responseParts, content.capacity(), false);
    // verify POST
    headers.add(RestUtils.Headers.BLOB_SIZE, content.capacity());
    headers.add(RestUtils.Headers.LIFE_VERSION, "0");
    getBlobAndVerify(blobId, null, GetOption.None, false, headers, !container.isCacheable(), content, account.getName(), container.getName());
    getBlobInfoAndVerify(blobId, GetOption.None, headers, !container.isCacheable(), account.getName(), container.getName(), null);
    // GET
    // Get signed URL
    HttpHeaders getHeaders = new DefaultHttpHeaders();
    getHeaders.add(RestUtils.Headers.URL_TYPE, RestMethod.GET.name());
    getHeaders.add(RestUtils.Headers.BLOB_ID, addClusterPrefix ? "/" + CLUSTER_NAME + blobId : blobId);
    httpRequest = buildRequest(HttpMethod.GET, Operations.GET_SIGNED_URL, getHeaders, null);
    responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    verifyTrackingHeaders(response);
    String signedGetUrl = response.headers().get(RestUtils.Headers.SIGNED_URL);
    assertNotNull("Did not get a signed GET URL", signedGetUrl);
    assertNoContent(responseParts.queue, 1);
    // Use URL to GET blob
    uri = new URI(signedGetUrl);
    httpRequest = buildRequest(HttpMethod.GET, uri.getPath() + "?" + uri.getQuery(), null, null);
    responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    verifyGetBlobResponse(responseParts, null, false, headers, !container.isCacheable(), content, account.getName(), container.getName());
}
Also used : Account(com.github.ambry.account.Account) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) Container(com.github.ambry.account.Container) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) HttpResponse(io.netty.handler.codec.http.HttpResponse) ResponseParts(com.github.ambry.rest.NettyClient.ResponseParts) ByteBuffer(java.nio.ByteBuffer) URI(java.net.URI) Test(org.junit.Test)

Example 17 with ResponseParts

use of com.github.ambry.rest.NettyClient.ResponseParts in project ambry by linkedin.

the class FrontendIntegrationTest method emptyBlobRangeHandlingTest.

@Test
public void emptyBlobRangeHandlingTest() throws Exception {
    Account refAccount = ACCOUNT_SERVICE.createAndAddRandomAccount();
    Container refContainer = refAccount.getContainerById(Container.DEFAULT_PUBLIC_CONTAINER_ID);
    HttpHeaders headers = new DefaultHttpHeaders();
    setAmbryHeadersForPut(headers, TTL_SECS, !refContainer.isCacheable(), refAccount.getName(), "application/octet-stream", null, refAccount.getName(), refContainer.getName());
    ByteBuffer content = ByteBuffer.allocate(0);
    String blobId = postBlobAndVerify(headers, content, content.capacity());
    ByteRange range = ByteRanges.fromOffsetRange(0, 50);
    headers.add(RestUtils.Headers.BLOB_SIZE, content.capacity());
    headers.add(RestUtils.Headers.LIFE_VERSION, "0");
    // Should get a 416 if x-ambry-resolve-range-on-empty-blob is not set
    HttpRequest httpRequest = buildRequest(HttpMethod.GET, blobId, new DefaultHttpHeaders().add(RestUtils.Headers.RANGE, RestTestUtils.getRangeHeaderString(range)), null);
    ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.REQUESTED_RANGE_NOT_SATISFIABLE, response.status());
    // Should get a 206 if the header is set.
    getBlobAndVerify(blobId, range, null, true, headers, !refContainer.isCacheable(), content, refAccount.getName(), refContainer.getName());
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) Account(com.github.ambry.account.Account) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) Container(com.github.ambry.account.Container) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) ByteRange(com.github.ambry.router.ByteRange) HttpResponse(io.netty.handler.codec.http.HttpResponse) ResponseParts(com.github.ambry.rest.NettyClient.ResponseParts) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 18 with ResponseParts

use of com.github.ambry.rest.NettyClient.ResponseParts in project ambry by linkedin.

the class FrontendIntegrationTest method uploadDataChunksAndVerify.

/**
 * Upload data chunks using chunk upload signed URL.
 * @param account the {@link Account} to upload into.
 * @param container the {@link Container} to upload into.
 * @param chunkSizes The sizes for each data chunk to upload.
 * @return the list of signed chunk IDs for the uploaded chunks and an array containing the concatenated content of
 *         the data chunks.
 * @throws Exception
 */
private Pair<List<String>, byte[]> uploadDataChunksAndVerify(Account account, Container container, int... chunkSizes) throws Exception {
    IdSigningService idSigningService = new AmbryIdSigningService();
    HttpHeaders chunkUploadHeaders = new DefaultHttpHeaders();
    chunkUploadHeaders.add(RestUtils.Headers.URL_TYPE, RestMethod.POST.name());
    chunkUploadHeaders.add(RestUtils.Headers.CHUNK_UPLOAD, "true");
    setAmbryHeadersForPut(chunkUploadHeaders, TTL_SECS, !container.isCacheable(), "chunkUploader", "application/octet-stream", "stitchedUploadTest", account.getName(), container.getName());
    // POST
    // Get signed URL
    FullHttpRequest httpRequest = buildRequest(HttpMethod.GET, Operations.GET_SIGNED_URL, chunkUploadHeaders, null);
    ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    verifyTrackingHeaders(response);
    String signedPostUrl = response.headers().get(RestUtils.Headers.SIGNED_URL);
    assertNotNull("Did not get a signed POST URL", signedPostUrl);
    assertNoContent(responseParts.queue, 1);
    List<String> signedChunkIds = new ArrayList<>();
    ByteArrayOutputStream fullContentStream = new ByteArrayOutputStream();
    URI uri = new URI(signedPostUrl);
    for (int chunkSize : chunkSizes) {
        byte[] contentArray = TestUtils.getRandomBytes(chunkSize);
        ByteBuffer content = ByteBuffer.wrap(contentArray);
        // Use signed URL to POST
        httpRequest = buildRequest(HttpMethod.POST, uri.getPath() + "?" + uri.getQuery(), null, content);
        responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
        String signedId = verifyPostAndReturnBlobId(responseParts, chunkSize, false);
        assertTrue("Blob ID for chunk upload must be signed", idSigningService.isIdSigned(signedId.substring(1)));
        Pair<String, Map<String, String>> idAndMetadata = idSigningService.parseSignedId(signedId.substring(1));
        // Inspect metadata fields
        String chunkUploadSession = idAndMetadata.getSecond().get(RestUtils.Headers.SESSION);
        assertNotNull("x-ambry-chunk-upload-session should be present in signed ID", chunkUploadSession);
        String blobSize = idAndMetadata.getSecond().get(RestUtils.Headers.BLOB_SIZE);
        assertNotNull("x-ambry-blob-size should be present in signed ID", blobSize);
        assertEquals("wrong size value in signed id", content.capacity(), Long.parseLong(blobSize));
        HttpHeaders expectedGetHeaders = new DefaultHttpHeaders().add(chunkUploadHeaders);
        // Use signed ID and blob ID for GET request
        expectedGetHeaders.add(RestUtils.Headers.BLOB_SIZE, content.capacity());
        // Blob TTL for chunk upload is fixed
        expectedGetHeaders.set(RestUtils.Headers.TTL, FRONTEND_CONFIG.chunkUploadInitialChunkTtlSecs);
        expectedGetHeaders.set(RestUtils.Headers.LIFE_VERSION, "0");
        for (String id : new String[] { signedId, idAndMetadata.getFirst() }) {
            getBlobAndVerify(id, null, GetOption.None, false, expectedGetHeaders, !container.isCacheable(), content, account.getName(), container.getName());
            getBlobInfoAndVerify(id, GetOption.None, expectedGetHeaders, !container.isCacheable(), account.getName(), container.getName(), null);
        }
        signedChunkIds.add(addClusterPrefix ? "/" + CLUSTER_NAME + signedId : signedId);
        fullContentStream.write(contentArray);
    }
    return new Pair<>(signedChunkIds, fullContentStream.toByteArray());
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) ArrayList(java.util.ArrayList) HttpResponse(io.netty.handler.codec.http.HttpResponse) ResponseParts(com.github.ambry.rest.NettyClient.ResponseParts) ByteArrayOutputStream(java.io.ByteArrayOutputStream) URI(java.net.URI) ByteBuffer(java.nio.ByteBuffer) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) Map(java.util.Map) ClusterMap(com.github.ambry.clustermap.ClusterMap) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Pair(com.github.ambry.utils.Pair)

Example 19 with ResponseParts

use of com.github.ambry.rest.NettyClient.ResponseParts in project ambry by linkedin.

the class FrontendIntegrationTest method healthCheckRequestTest.

/**
 * Tests health check request
 * @throws ExecutionException
 * @throws InterruptedException
 */
@Test
public void healthCheckRequestTest() throws ExecutionException, InterruptedException {
    FullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/healthCheck", Unpooled.buffer(0));
    ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    final String expectedResponseBody = "GOOD";
    ByteBuffer content = getContent(responseParts.queue, expectedResponseBody.length());
    assertEquals("GET content does not match original content", expectedResponseBody, new String(content.array()));
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpResponse(io.netty.handler.codec.http.HttpResponse) ResponseParts(com.github.ambry.rest.NettyClient.ResponseParts) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 20 with ResponseParts

use of com.github.ambry.rest.NettyClient.ResponseParts in project ambry by linkedin.

the class FrontendIntegrationTest method optionsTest.

/**
 * Tests for handling of {@link HttpMethod#OPTIONS}.
 * @throws Exception
 */
@Test
public void optionsTest() throws Exception {
    FullHttpRequest httpRequest = buildRequest(HttpMethod.OPTIONS, "", null, null);
    ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    assertTrue("No Date header", response.headers().getTimeMillis(HttpHeaderNames.DATE, -1) != -1);
    assertEquals("Content-Length is not 0", 0, HttpUtil.getContentLength(response));
    assertEquals("Unexpected value for " + HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, FRONTEND_CONFIG.optionsAllowMethods, response.headers().get(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS));
    assertEquals("Unexpected value for " + HttpHeaderNames.ACCESS_CONTROL_MAX_AGE, FRONTEND_CONFIG.optionsValiditySeconds, Long.parseLong(response.headers().get(HttpHeaderNames.ACCESS_CONTROL_MAX_AGE)));
    verifyTrackingHeaders(response);
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) HttpResponse(io.netty.handler.codec.http.HttpResponse) ResponseParts(com.github.ambry.rest.NettyClient.ResponseParts) Test(org.junit.Test)

Aggregations

ResponseParts (com.github.ambry.rest.NettyClient.ResponseParts)22 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)21 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)21 HttpResponse (io.netty.handler.codec.http.HttpResponse)18 DefaultHttpHeaders (io.netty.handler.codec.http.DefaultHttpHeaders)15 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)15 ByteBuffer (java.nio.ByteBuffer)11 Test (org.junit.Test)9 Container (com.github.ambry.account.Container)5 HttpRequest (io.netty.handler.codec.http.HttpRequest)5 Account (com.github.ambry.account.Account)4 HttpPostRequestEncoder (io.netty.handler.codec.http.multipart.HttpPostRequestEncoder)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3 NettyConfig (com.github.ambry.config.NettyConfig)2 ByteRange (com.github.ambry.router.ByteRange)2 URI (java.net.URI)2 ArrayList (java.util.ArrayList)2 JSONObject (org.json.JSONObject)2 ClusterMap (com.github.ambry.clustermap.ClusterMap)1 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)1