use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class AbstractCaptureFilterTest method testException.
@Test
public void testException() {
final RestRequest req = request();
final Exception ex = new Exception();
FilterUtil.fireUntypedRequestError(getFilterChain(), req, ex);
// Request / response should not be recorded
Assert.assertNull(getDb().replay(req));
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class AbstractCaptureFilterTest method testSameRequestDifferentResponses.
@Test
public void testSameRequestDifferentResponses() {
final RestRequest req = request();
final RestResponse res1 = response();
final RestResponse res2 = res1.builder().setEntity("This is a different response".getBytes()).build();
FilterUtil.fireUntypedRequestResponse(getFilterChain(), req, res1);
FilterUtil.fireUntypedRequestResponse(getFilterChain(), req, res2);
// Last one wins
Assert.assertEquals(res2, getDb().<Response>replay(req));
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class AbstractReplayFilterTest method testReplayWithNoMatch.
@Test
public void testReplayWithNoMatch() {
final RestRequest req = request();
final RestResponse res = response();
final CaptureLastCallFilter captureFilter = new CaptureLastCallFilter();
final FilterChain fc = getFilterChain().addFirstRest(captureFilter);
FilterUtil.fireUntypedRequestResponse(fc, req, res);
Assert.assertEquals(res, captureFilter.getLastRes());
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class HttpDispatcher method handleRequest.
/**
* handle a {@link com.linkedin.r2.message.stream.StreamRequest} using the given request context.
* @see com.linkedin.r2.transport.common.bridge.server.TransportDispatcher#handleStreamRequest
*
* @param req the request to be handled.
* @param context the request context.
* @param callback the callback to be invoked with the response or error.
*/
public void handleRequest(StreamRequest req, RequestContext context, final TransportCallback<StreamResponse> callback) {
markOnRequestTimings(context);
final Map<String, String> headers = new HashMap<>(req.getHeaders());
final Map<String, String> wireAttrs = WireAttributeHelper.removeWireAttributes(headers);
final BaseConnector connector = new BaseConnector();
try {
MessageType.Type msgType = MessageType.getMessageType(wireAttrs, MessageType.Type.REST);
switch(msgType) {
default:
case REST:
req.getEntityStream().setReader(connector);
StreamRequest newReq = req.builder().build(EntityStreams.newEntityStream(connector));
// decorate the call back so that if response is error or response finishes streaming,
// we cancel the request stream
TransportCallback<StreamResponse> decorateCallback = new TransportCallback<StreamResponse>() {
@Override
public void onResponse(TransportResponse<StreamResponse> response) {
// no need to check StreamException because that's handled by HttpBridge.httpToStreamCallback
if (response.hasError()) {
connector.cancel();
} else {
Observer observer = new Observer() {
@Override
public void onDataAvailable(ByteString data) {
// do nothing
}
@Override
public void onDone() {
connector.cancel();
}
@Override
public void onError(Throwable e) {
connector.cancel();
}
};
response.getResponse().getEntityStream().addObserver(observer);
}
callback.onResponse(response);
}
};
_dispatcher.handleStreamRequest(HttpBridge.toStreamRequest(newReq, headers), wireAttrs, context, HttpBridge.httpToStreamCallback(decorateCallback));
}
} catch (Exception e) {
connector.cancel();
callback.onResponse(TransportResponseImpl.<StreamResponse>error(e, Collections.<String, String>emptyMap()));
}
}
use of com.linkedin.r2.message.Response in project rest.li by linkedin.
the class SyncIOHandler method eventLoop.
private void eventLoop() throws ServletException, IOException, InterruptedException, TimeoutException {
final long startTime = System.currentTimeMillis();
byte[] buf = new byte[DEFAULT_DATA_CHUNK_SIZE];
while (shouldContinue() && !_forceExit) {
long timeSpent = System.currentTimeMillis() - startTime;
long maxWaitTime = timeSpent < _timeout ? _timeout - timeSpent : 0;
Event event = _eventQueue.poll(maxWaitTime, TimeUnit.MILLISECONDS);
if (event == null) {
throw new TimeoutException("Timeout after " + _timeout + " milliseconds.");
}
switch(event.getEventType()) {
case ResponseDataAvailable:
{
ByteString data = (ByteString) event.getData();
data.write(_os);
_rh.request(1);
break;
}
case WriteRequestPossible:
{
while (_wh.remaining() > 0) {
final int actualLen = _is.read(buf);
if (actualLen < 0) {
_wh.done();
_requestReadFinished = true;
break;
}
_wh.write(ByteString.copy(buf, 0, actualLen));
}
break;
}
case FullResponseReceived:
{
_os.close();
_responseWriteFinished = true;
break;
}
case ResponseDataError:
{
_os.close();
_responseWriteFinished = true;
break;
}
case WriteRequestAborted:
{
if (event.getData() instanceof AbortedException) {
// reader cancels, we'll drain the stream on behalf of reader
// we don't directly drain it here because we'd like to give other events
// some opportunities to be executed; e.g. return an error response
_eventQueue.add(Event.DrainRequestEvent);
} else {
// TODO: do we want to be smarter and return server error response?
throw new ServletException((Throwable) event.getData());
}
break;
}
case DrainRequest:
{
for (int i = 0; i < 10; i++) {
final int actualLen = _is.read(buf);
if (actualLen < 0) {
_requestReadFinished = true;
break;
}
}
if (!_requestReadFinished) {
// add self back to event queue and give others a chance to run
_eventQueue.add(Event.DrainRequestEvent);
}
break;
}
case ForceExit:
{
_forceExit = true;
break;
}
default:
throw new IllegalStateException("Unknown event type:" + event.getEventType());
}
}
}
Aggregations