Search in sources :

Example 16 with FutureResult

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

the class NamedBlobPutHandlerTest method doTtlRequiredEnforcementTest.

/**
 * Does the TTL required enforcement test by selecting the right verification methods based on container and frontend
 * config
 * @param container the {@link Container} to upload to
 * @param blobTtlSecs the TTL to set for the blob
 * @throws Exception
 */
private void doTtlRequiredEnforcementTest(Container container, long blobTtlSecs) throws Exception {
    JSONObject headers = new JSONObject();
    FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, blobTtlSecs, !container.isCacheable(), SERVICE_ID, CONTENT_TYPE, OWNER_ID, null, null, null);
    byte[] content = TestUtils.getRandomBytes(1024);
    RestRequest request = getRestRequest(headers, request_path, content);
    RestResponseChannel restResponseChannel = new MockRestResponseChannel();
    FutureResult<Void> future = new FutureResult<>();
    namedBlobPutHandler.handle(request, restResponseChannel, future::done);
    if (container.isTtlRequired() && (blobTtlSecs == Utils.Infinite_Time || blobTtlSecs > frontendConfig.maxAcceptableTtlSecsIfTtlRequired)) {
        if (frontendConfig.failIfTtlRequiredButNotProvided) {
            try {
                future.get(TIMEOUT_SECS, TimeUnit.SECONDS);
                fail("Post should have failed");
            } catch (ExecutionException e) {
                RestServiceException rootCause = (RestServiceException) Utils.getRootCause(e);
                assertNotNull("Root cause should be a RestServiceException", rootCause);
                assertEquals("Incorrect RestServiceErrorCode", RestServiceErrorCode.InvalidArgs, rootCause.getErrorCode());
            }
        } else {
            verifySuccessResponseOnTtlEnforcement(future, content, blobTtlSecs, restResponseChannel, true);
        }
    } else {
        verifySuccessResponseOnTtlEnforcement(future, content, blobTtlSecs, restResponseChannel, false);
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) 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) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) ExecutionException(java.util.concurrent.ExecutionException)

Example 17 with FutureResult

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

the class PostAccountsHandlerTest method sendRequestGetResponse.

// helpers
// general
/**
 * Sends a request to the {@link PostAccountsHandler} and waits for the response.
 * @param requestBody body of the request in string form.
 * @param restResponseChannel the {@link RestResponseChannel} where headers will be set.
 * @throws Exception
 */
private void sendRequestGetResponse(String requestBody, RestResponseChannel restResponseChannel) throws Exception {
    JSONObject data = new JSONObject();
    data.put(MockRestRequest.REST_METHOD_KEY, RestMethod.POST.name());
    data.put(MockRestRequest.URI_KEY, Operations.ACCOUNTS);
    List<ByteBuffer> body = new LinkedList<>();
    body.add(ByteBuffer.wrap(requestBody.getBytes(StandardCharsets.UTF_8)));
    body.add(null);
    RestRequest restRequest = new MockRestRequest(data, body);
    restRequest.setArg(RestUtils.InternalKeys.REQUEST_PATH, RequestPath.parse(restRequest, null, null));
    FutureResult<ReadableStreamChannel> future = new FutureResult<>();
    handler.handle(restRequest, restResponseChannel, future::done);
    try {
        future.get(1, TimeUnit.SECONDS);
    } catch (ExecutionException e) {
        throw e.getCause() instanceof Exception ? (Exception) e.getCause() : new Exception(e.getCause());
    }
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) JSONObject(org.json.JSONObject) FutureResult(com.github.ambry.router.FutureResult) ReadableStreamChannel(com.github.ambry.router.ReadableStreamChannel) MockRestRequest(com.github.ambry.rest.MockRestRequest) ExecutionException(java.util.concurrent.ExecutionException) ByteBuffer(java.nio.ByteBuffer) LinkedList(java.util.LinkedList) ExecutionException(java.util.concurrent.ExecutionException) RestServiceException(com.github.ambry.rest.RestServiceException)

Example 18 with FutureResult

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

the class PostBlobHandlerTest method doTtlRequiredEnforcementTest.

// ttlRequiredEnforcementTest() helpers
/**
 * Does the TTL required enforcement test by selecting the right verification methods based on container and frontend
 * config
 * @param container the {@link Container} to upload to
 * @param blobTtlSecs the TTL to set for the blob
 * @throws Exception
 */
private void doTtlRequiredEnforcementTest(Container container, long blobTtlSecs) throws Exception {
    JSONObject headers = new JSONObject();
    FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, blobTtlSecs, !container.isCacheable(), SERVICE_ID, CONTENT_TYPE, OWNER_ID, REF_ACCOUNT.getName(), container.getName(), null);
    byte[] content = TestUtils.getRandomBytes(1024);
    RestRequest request = getRestRequest(headers, "/", content);
    RestResponseChannel restResponseChannel = new MockRestResponseChannel();
    FutureResult<Void> future = new FutureResult<>();
    postBlobHandler.handle(request, restResponseChannel, future::done);
    if (container.isTtlRequired() && (blobTtlSecs == Utils.Infinite_Time || blobTtlSecs > frontendConfig.maxAcceptableTtlSecsIfTtlRequired)) {
        if (frontendConfig.failIfTtlRequiredButNotProvided) {
            try {
                future.get(TIMEOUT_SECS, TimeUnit.SECONDS);
                fail("Post should have failed");
            } catch (ExecutionException e) {
                RestServiceException rootCause = (RestServiceException) Utils.getRootCause(e);
                assertNotNull("Root cause should be a RestServiceException", rootCause);
                assertEquals("Incorrect RestServiceErrorCode", RestServiceErrorCode.InvalidArgs, rootCause.getErrorCode());
            }
        } else {
            verifySuccessResponseOnTtlEnforcement(future, content, blobTtlSecs, restResponseChannel, true);
        }
    } else {
        verifySuccessResponseOnTtlEnforcement(future, content, blobTtlSecs, restResponseChannel, false);
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) 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) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) ExecutionException(java.util.concurrent.ExecutionException)

Example 19 with FutureResult

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

the class NettyResponseChannel method write.

@Override
public Future<Long> write(ByteBuf src, Callback<Long> callback) {
    long writeProcessingStartTime = System.currentTimeMillis();
    if (!responseMetadataWriteInitiated.get()) {
        maybeWriteResponseMetadata(responseMetadata, new ResponseMetadataWriteListener());
    }
    if (finalResponseMetadata == null) {
        // If finalResponseMetadata is still null, it indicates channel becomes inactive.
        if (ctx.channel().isActive()) {
            logger.warn("Channel should be inactive status. {}", ctx.channel());
            nettyMetrics.channelStatusInconsistentCount.inc();
        } else {
            logger.debug("Scheduling a chunk cleanup on channel {} because response channel is closed.", ctx.channel());
            writeFuture.addListener(new CleanupCallback(new ClosedChannelException()));
        }
        FutureResult<Long> future = new FutureResult<Long>();
        future.done(0L, new ClosedChannelException());
        if (callback != null) {
            callback.onCompletion(0L, new ClosedChannelException());
        }
        return future;
    }
    Chunk chunk = new Chunk(src, callback);
    logger.debug("Netty Response Chunk size: {}", src.readableBytes());
    chunksToWrite.add(chunk);
    if (HttpUtil.isContentLengthSet(finalResponseMetadata) && totalBytesReceived.get() > HttpUtil.getContentLength(finalResponseMetadata)) {
        Exception exception = new IllegalStateException("Size of provided content [" + totalBytesReceived.get() + "] is greater than Content-Length set [" + HttpUtil.getContentLength(finalResponseMetadata) + "]");
        if (!writeFuture.isDone()) {
            writeFuture.setFailure(exception);
        }
        writeFuture.addListener(new CleanupCallback(exception));
    } else if (!isOpen()) {
        // the isOpen() check is not before addition to the queue because chunks need to be acknowledged in the order
        // they were received. If we don't add it to the queue and clean up, chunks may be acknowledged out of order.
        logger.debug("Scheduling a chunk cleanup on channel {} because response channel is closed", ctx.channel());
        writeFuture.addListener(new CleanupCallback(new ClosedChannelException()));
    } else if (finalResponseMetadata instanceof FullHttpResponse) {
        logger.debug("Scheduling a chunk cleanup on channel {} because Content-Length is 0", ctx.channel());
        Exception exception = null;
        // this is only allowed to be a 0 sized buffer.
        if (src.readableBytes() > 0) {
            exception = new IllegalStateException("Provided non zero size content after setting Content-Length to 0");
            if (!writeFuture.isDone()) {
                writeFuture.setFailure(exception);
            }
        }
        writeFuture.addListener(new CleanupCallback(exception));
    } else {
        chunkedWriteHandler.resumeTransfer();
    }
    long writeProcessingTime = System.currentTimeMillis() - writeProcessingStartTime;
    nettyMetrics.writeProcessingTimeInMs.update(writeProcessingTime);
    if (request != null) {
        request.getMetricsTracker().nioMetricsTracker.addToResponseProcessingTime(writeProcessingTime);
    }
    return chunk.future;
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) FutureResult(com.github.ambry.router.FutureResult) AtomicLong(java.util.concurrent.atomic.AtomicLong) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) ClosedChannelException(java.nio.channels.ClosedChannelException)

Example 20 with FutureResult

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

the class BadRestRequest method readInto.

/**
 * Either throws the exception provided or returns immediately saying no bytes were read.
 * @param asyncWritableChannel the {@link AsyncWritableChannel} to read the data into.
 * @param callback the {@link Callback} that will be invoked either when all the data in the channel has been emptied
 *                 into the {@code asyncWritableChannel} or if there is an exception in doing so. This can be null.
 * @return a {@link Future} that will eventually contain the result of the operation.
 */
@Override
public Future<Long> readInto(AsyncWritableChannel asyncWritableChannel, Callback<Long> callback) {
    Exception exception;
    if (!channelOpen.get()) {
        exception = new ClosedChannelException();
    } else {
        exception = exceptionToThrow;
    }
    FutureResult<Long> futureResult = new FutureResult<Long>();
    futureResult.done(bytesRead, exception);
    if (callback != null) {
        callback.onCompletion(bytesRead, exception);
    }
    return futureResult;
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) FutureResult(com.github.ambry.router.FutureResult) URISyntaxException(java.net.URISyntaxException) JSONException(org.json.JSONException) ClosedChannelException(java.nio.channels.ClosedChannelException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Aggregations

FutureResult (com.github.ambry.router.FutureResult)22 IOException (java.io.IOException)8 RestRequest (com.github.ambry.rest.RestRequest)7 RestServiceException (com.github.ambry.rest.RestServiceException)7 JSONObject (org.json.JSONObject)7 MockRestResponseChannel (com.github.ambry.rest.MockRestResponseChannel)6 RestResponseChannel (com.github.ambry.rest.RestResponseChannel)6 RouterException (com.github.ambry.router.RouterException)6 ClosedChannelException (java.nio.channels.ClosedChannelException)6 ExecutionException (java.util.concurrent.ExecutionException)5 GetBlobResult (com.github.ambry.router.GetBlobResult)4 InMemoryRouter (com.github.ambry.router.InMemoryRouter)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)4 URISyntaxException (java.net.URISyntaxException)4 ByteBufferReadableStreamChannel (com.github.ambry.commons.ByteBufferReadableStreamChannel)3 BlobInfo (com.github.ambry.messageformat.BlobInfo)3 ByteBuffer (java.nio.ByteBuffer)3 HashMap (java.util.HashMap)3 AtomicLong (java.util.concurrent.atomic.AtomicLong)3 MetricRegistry (com.codahale.metrics.MetricRegistry)2