use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class RAPResponseDecoder method channelRead0.
@Override
protected void channelRead0(final ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpResponse) {
HttpResponse m = (HttpResponse) msg;
_shouldCloseConnection = !HttpUtil.isKeepAlive(m);
if (HttpUtil.is100ContinueExpected(m)) {
ctx.writeAndFlush(CONTINUE).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
ctx.fireExceptionCaught(future.cause());
}
}
});
}
if (!m.decoderResult().isSuccess()) {
ctx.fireExceptionCaught(m.decoderResult().cause());
return;
}
// remove chunked encoding.
if (HttpUtil.isTransferEncodingChunked(m)) {
HttpUtil.setTransferEncodingChunked(m, false);
}
Timeout<None> timeout = ctx.channel().attr(TIMEOUT_ATTR_KEY).getAndRemove();
if (timeout == null) {
LOG.debug("dropped a response after channel inactive or exception had happened.");
return;
}
final TimeoutBufferedWriter writer = new TimeoutBufferedWriter(ctx, _maxContentLength, BUFFER_HIGH_WATER_MARK, BUFFER_LOW_WATER_MARK, timeout);
EntityStream entityStream = EntityStreams.newEntityStream(writer);
_chunkedMessageWriter = writer;
StreamResponseBuilder builder = new StreamResponseBuilder();
builder.setStatus(m.status().code());
for (Map.Entry<String, String> e : m.headers()) {
String key = e.getKey();
String value = e.getValue();
if (key.equalsIgnoreCase(HttpConstants.RESPONSE_COOKIE_HEADER_NAME)) {
builder.addCookie(value);
} else {
builder.unsafeAddHeaderValue(key, value);
}
}
ctx.fireChannelRead(builder.build(entityStream));
} else if (msg instanceof HttpContent) {
HttpContent chunk = (HttpContent) msg;
TimeoutBufferedWriter currentWriter = _chunkedMessageWriter;
// Sanity check
if (currentWriter == null) {
throw new IllegalStateException("received " + HttpContent.class.getSimpleName() + " without " + HttpResponse.class.getSimpleName());
}
if (!chunk.decoderResult().isSuccess()) {
this.exceptionCaught(ctx, chunk.decoderResult().cause());
}
currentWriter.processHttpChunk(chunk);
if (chunk instanceof LastHttpContent) {
_chunkedMessageWriter = null;
}
} else {
// something must be wrong, but let's proceed so that
// handler after us has a chance to process it.
ctx.fireChannelRead(msg);
}
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class RestClientTest method testRestLiRemoteInvocationException.
@Test(dataProvider = TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "sendRequestOptions")
public void testRestLiRemoteInvocationException(SendRequestOption option, TimeoutOption timeoutOption, ProtocolVersionOption versionOption, ProtocolVersion protocolVersion, String errorResponseHeaderName) throws ExecutionException, TimeoutException, InterruptedException, RestLiDecodingException {
final int HTTP_CODE = 404;
final String ERR_MSG = "WHOOPS!";
RestClient client = mockClient(HTTP_CODE, ERR_MSG, protocolVersion);
Request<EmptyRecord> request = mockRequest(EmptyRecord.class, versionOption);
RequestBuilder<Request<EmptyRecord>> requestBuilder = mockRequestBuilder(request);
FutureCallback<Response<EmptyRecord>> callback = new FutureCallback<Response<EmptyRecord>>();
try {
sendRequest(option, client, request, requestBuilder, callback);
Long l = timeoutOption._l;
TimeUnit timeUnit = timeoutOption._timeUnit;
Response<EmptyRecord> response = l == null ? callback.get() : callback.get(l, timeUnit);
Assert.fail("Should have thrown");
} catch (ExecutionException e) {
Throwable cause = e.getCause();
Assert.assertTrue(cause instanceof RemoteInvocationException, "Expected RemoteInvocationException not " + cause.getClass().getName());
RemoteInvocationException rlre = (RemoteInvocationException) cause;
Assert.assertTrue(rlre.getMessage().startsWith("Received error " + HTTP_CODE + " from server"));
Throwable rlCause = rlre.getCause();
Assert.assertTrue(rlCause instanceof RestException, "Excepted RestException not " + rlCause.getClass().getName());
RestException rle = (RestException) rlCause;
Assert.assertEquals(ERR_MSG, rle.getResponse().getEntity().asString("UTF-8"));
Assert.assertEquals(HTTP_CODE, rle.getResponse().getStatus());
}
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class RestClientTest method testRestLiResponseExceptionCallback.
@Test(dataProvider = TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "sendRequestOptions")
public void testRestLiResponseExceptionCallback(SendRequestOption option, TimeoutOption timeoutOption, ProtocolVersionOption versionOption, ProtocolVersion protocolVersion, String errorResponseHeaderName) throws ExecutionException, TimeoutException, InterruptedException, RestLiDecodingException {
final String ERR_KEY = "someErr";
final String ERR_VALUE = "WHOOPS!";
final String ERR_MSG = "whoops2";
final int HTTP_CODE = 400;
final int APP_CODE = 666;
RestClient client = mockClient(ERR_KEY, ERR_VALUE, ERR_MSG, HTTP_CODE, APP_CODE, protocolVersion, errorResponseHeaderName);
Request<EmptyRecord> request = mockRequest(EmptyRecord.class, versionOption);
RequestBuilder<Request<EmptyRecord>> requestBuilder = mockRequestBuilder(request);
FutureCallback<Response<EmptyRecord>> callback = new FutureCallback<Response<EmptyRecord>>();
try {
sendRequest(option, client, request, requestBuilder, callback);
Long l = timeoutOption._l;
TimeUnit timeUnit = timeoutOption._timeUnit;
Response<EmptyRecord> response = l == null ? callback.get() : callback.get(l, timeUnit);
Assert.fail("Should have thrown");
} catch (ExecutionException e) {
// New
Throwable cause = e.getCause();
Assert.assertTrue(cause instanceof RestLiResponseException, "Expected RestLiResponseException not " + cause.getClass().getName());
RestLiResponseException rlre = (RestLiResponseException) cause;
Assert.assertEquals(HTTP_CODE, rlre.getStatus());
Assert.assertEquals(ERR_VALUE, rlre.getErrorDetails().get(ERR_KEY));
Assert.assertEquals(APP_CODE, rlre.getServiceErrorCode());
Assert.assertEquals(ERR_MSG, rlre.getServiceErrorMessage());
// Old
Assert.assertTrue(cause instanceof RestException, "Expected RestException not " + cause.getClass().getName());
RestException re = (RestException) cause;
RestResponse r = re.getResponse();
ErrorResponse er = new EntityResponseDecoder<ErrorResponse>(ErrorResponse.class).decodeResponse(r).getEntity();
Assert.assertEquals(HTTP_CODE, r.getStatus());
Assert.assertEquals(ERR_VALUE, er.getErrorDetails().data().getString(ERR_KEY));
Assert.assertEquals(APP_CODE, er.getServiceErrorCode().intValue());
Assert.assertEquals(ERR_MSG, er.getMessage());
}
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class TestParseqTraceDebugRequestHandler method testResponseStreamingAttachmentsForbidden.
@Test
public void testResponseStreamingAttachmentsForbidden() {
//This test verifies that the ParseqTraceDebugRequestHandler aborts any potential outgoing response attachments
//set by a resource method.
final URI uri = URI.create("http://host/abc/12/__debug/parseqtrace/raw");
ParseqTraceDebugRequestHandler requestHandler = new ParseqTraceDebugRequestHandler();
RestRequestBuilder requestBuilder = new RestRequestBuilder(uri);
RestRequest request = requestBuilder.build();
RequestContext requestContext = new RequestContext();
final RequestExecutionCallback<RestResponse> callback = new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request execution failed unexpectedly.");
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
}
};
final RestLiTestAttachmentDataSource testAttachmentDataSource = RestLiTestAttachmentDataSource.createWithRandomPayload("1");
final RestLiResponseAttachments responseAttachments = new RestLiResponseAttachments.Builder().appendSingleAttachment(testAttachmentDataSource).build();
requestHandler.handleRequest(request, requestContext, new RestLiDebugRequestHandler.ResourceDebugRequestHandler() {
@Override
public void handleRequest(RestRequest request, RequestContext requestContext, RequestExecutionCallback<RestResponse> callback) {
RestResponse response = EasyMock.createMock(RestResponse.class);
//Provide some attachments that should be aborted.
callback.onSuccess(response, new RequestExecutionReportBuilder().build(), responseAttachments);
}
}, null, callback);
Assert.assertTrue(testAttachmentDataSource.dataSourceAborted());
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class TestParseqTraceDebugRequestHandler method executeRequestThroughParseqDebugHandler.
private void executeRequestThroughParseqDebugHandler(URI uri, RequestExecutionCallback<RestResponse> callback) {
ParseqTraceDebugRequestHandler requestHandler = new ParseqTraceDebugRequestHandler();
RestRequestBuilder requestBuilder = new RestRequestBuilder(uri);
RestRequest request = requestBuilder.build();
RequestContext requestContext = new RequestContext();
requestHandler.handleRequest(request, requestContext, new RestLiDebugRequestHandler.ResourceDebugRequestHandler() {
@Override
public void handleRequest(RestRequest request, RequestContext requestContext, RequestExecutionCallback<RestResponse> callback) {
RestResponse response = EasyMock.createMock(RestResponse.class);
RequestExecutionReportBuilder executionReportBuilder = new RequestExecutionReportBuilder();
JsonTraceCodec jsonTraceCodec = new JsonTraceCodec();
Trace t = null;
try {
t = jsonTraceCodec.decode(TEST_TRACE);
executionReportBuilder.setParseqTrace(t);
} catch (IOException exc) {
//test will fail later
}
callback.onSuccess(response, executionReportBuilder.build(), null);
}
}, null, callback);
}
Aggregations