/** * Gets the headers of the blob with blob ID {@code blobId} and verifies them against what is * expected. * * @param blobId the blob ID of the blob to HEAD. * @param range the {@link ByteRange} for the request. * @param expectedHeaders the expected headers in the response. * @throws ExecutionException * @throws InterruptedException */ private void getHeadAndVerify(String blobId, ByteRange range, HttpHeaders expectedHeaders) throws ExecutionException, InterruptedException, RestServiceException { HttpHeaders headers = null; if (range != null) { headers = new DefaultHttpHeaders() .add(RestUtils.Headers.RANGE, RestTestUtils.getRangeHeaderString(range)); } FullHttpRequest httpRequest = buildRequest(HttpMethod.HEAD, blobId, headers, null); Queue<HttpObject> responseParts = nettyClient.sendRequest(httpRequest, null, null).get(); HttpResponse response = (HttpResponse) responseParts.poll(); assertEquals( "Unexpected response status", range == null ? HttpResponseStatus.OK : HttpResponseStatus.PARTIAL_CONTENT, response.getStatus()); checkCommonGetHeadHeaders(response.headers()); long contentLength = Long.parseLong(expectedHeaders.get(RestUtils.Headers.BLOB_SIZE)); if (range != null) { Pair<String, Long> rangeAndLength = RestUtils.buildContentRangeAndLength(range, contentLength); assertEquals( "Content-Range header not set correctly", rangeAndLength.getFirst(), response.headers().get(RestUtils.Headers.CONTENT_RANGE)); contentLength = rangeAndLength.getSecond(); } else { assertNull( "Content-Range header should not be set", response.headers().get(RestUtils.Headers.CONTENT_RANGE)); } assertEquals( "Accept-Ranges not set correctly", "bytes", response.headers().get(RestUtils.Headers.ACCEPT_RANGES)); assertEquals( RestUtils.Headers.CONTENT_LENGTH + " does not match expected", contentLength, HttpHeaders.getContentLength(response)); assertEquals( RestUtils.Headers.CONTENT_TYPE + " does not match " + RestUtils.Headers.AMBRY_CONTENT_TYPE, expectedHeaders.get(RestUtils.Headers.AMBRY_CONTENT_TYPE), HttpHeaders.getHeader(response, HttpHeaders.Names.CONTENT_TYPE)); verifyBlobProperties(expectedHeaders, response); discardContent(responseParts, 1); assertTrue("Channel should be active", HttpHeaders.isKeepAlive(response)); }
/** * Gets a view of the given {@code segment} and verifies the ref count and the data obtained from * the view against {@code expectedRefCount} and {@code dataInSegment} respectively. * * @param segment the {@link LogSegment} to get a view from. * @param writeStartOffset the offset at which write was started on the segment. * @param offset the offset for which a view is required. * @param dataInSegment the entire data in the {@link LogSegment}. * @param expectedRefCount the expected return value of {@link LogSegment#refCount()} once the * view is obtained from the {@code segment} * @throws IOException */ private void getAndVerifyView( LogSegment segment, long writeStartOffset, int offset, byte[] dataInSegment, long expectedRefCount) throws IOException { Random random = new Random(); Pair<File, FileChannel> view = segment.getView(); assertNotNull("File object received in view is null", view.getFirst()); assertNotNull("FileChannel object received in view is null", view.getSecond()); assertEquals("Ref count is not as expected", expectedRefCount, segment.refCount()); int sizeToRead = random.nextInt(dataInSegment.length - offset + 1); ByteBuffer buffer = ByteBuffer.wrap(new byte[sizeToRead]); view.getSecond().read(buffer, writeStartOffset + offset); assertArrayEquals( "Data read from file does not match data written", Arrays.copyOfRange(dataInSegment, offset, offset + sizeToRead), buffer.array()); }