@Test public void testOnBodyPartReceivedWithResumableListenerThrowsException() throws Exception { ResumableAsyncHandler handler = new ResumableAsyncHandler(); ResumableListener resumableListener = mock(ResumableListener.class); doThrow(new IOException()).when(resumableListener).onBytesReceived(any()); handler.setResumableListener(resumableListener); HttpResponseBodyPart bodyPart = mock(HttpResponseBodyPart.class); State state = handler.onBodyPartReceived(bodyPart); assertEquals(state, AsyncHandler.State.ABORT, "State should be ABORT if the resumableListener threw an exception in onBodyPartReceived"); }
@Test public void testOnHeadersReceived() throws Exception { ResumableAsyncHandler handler = new ResumableAsyncHandler(); HttpHeaders responseHeaders = new DefaultHttpHeaders(); State status = handler.onHeadersReceived(responseHeaders); assertEquals(status, AsyncHandler.State.CONTINUE, "State should be CONTINUE for a successful onHeadersReceived"); }
@Test public void testOnStatusReceived500Status() throws Exception { MapResumableProcessor processor = new MapResumableProcessor(); ResumableAsyncHandler handler = new ResumableAsyncHandler(processor); HttpResponseStatus mockResponseStatus = mock(HttpResponseStatus.class); when(mockResponseStatus.getStatusCode()).thenReturn(500); when(mockResponseStatus.getUri()).thenReturn(mock(Uri.class)); State state = handler.onStatusReceived(mockResponseStatus); assertEquals(state, AsyncHandler.State.ABORT, "State should be ABORT for Internal Server Error status"); }
@Test public void testOnBodyPartReceived() throws Exception { ResumableAsyncHandler handler = new ResumableAsyncHandler(); HttpResponseBodyPart bodyPart = mock(HttpResponseBodyPart.class); when(bodyPart.getBodyPartBytes()).thenReturn(new byte[0]); ByteBuffer buffer = ByteBuffer.allocate(0); when(bodyPart.getBodyByteBuffer()).thenReturn(buffer); State state = handler.onBodyPartReceived(bodyPart); assertEquals(state, AsyncHandler.State.CONTINUE, "State should be CONTINUE for a successful onBodyPartReceived"); }
public <T> FilterContext<T> filter(FilterContext<T> ctx) { if (ctx.getIOException() != null && ctx.getAsyncHandler() instanceof ResumableAsyncHandler) { Request request = ResumableAsyncHandler.class.cast(ctx.getAsyncHandler()).adjustRequestRange(ctx.getRequest()); return new FilterContext.FilterContextBuilder<>(ctx).request(request).replayRequest(true).build(); } return ctx; } }
@Test public void testAdjustRange() { MapResumableProcessor proc = new MapResumableProcessor(); ResumableAsyncHandler handler = new ResumableAsyncHandler(proc); Request request = get("http://test/url").build(); Request newRequest = handler.adjustRequestRange(request); assertEquals(newRequest.getUri(), request.getUri()); String rangeHeader = newRequest.getHeaders().get(RANGE); assertNull(rangeHeader); proc.put("http://test/url", 5000); newRequest = handler.adjustRequestRange(request); assertEquals(newRequest.getUri(), request.getUri()); rangeHeader = newRequest.getHeaders().get(RANGE); assertEquals(rangeHeader, "bytes=5000-"); }
@Test public void testOnBodyPartReceivedWithDecoratedAsyncHandler() throws Exception { HttpResponseBodyPart bodyPart = mock(HttpResponseBodyPart.class); when(bodyPart.getBodyPartBytes()).thenReturn(new byte[0]); ByteBuffer buffer = ByteBuffer.allocate(0); when(bodyPart.getBodyByteBuffer()).thenReturn(buffer); @SuppressWarnings("unchecked") AsyncHandler<Response> decoratedAsyncHandler = mock(AsyncHandler.class); when(decoratedAsyncHandler.onBodyPartReceived(bodyPart)).thenReturn(State.CONTINUE); // following is needed to set the url variable HttpResponseStatus mockResponseStatus = mock(HttpResponseStatus.class); when(mockResponseStatus.getStatusCode()).thenReturn(200); Uri uri = Uri.create("http://non.null"); when(mockResponseStatus.getUri()).thenReturn(uri); ResumableAsyncHandler handler = new ResumableAsyncHandler(decoratedAsyncHandler); handler.onStatusReceived(mockResponseStatus); State state = handler.onBodyPartReceived(bodyPart); assertEquals(state, State.CONTINUE, "State should be equal to the state returned from decoratedAsyncHandler"); }
/** * Configure and execute the associated {@link RequestFilter}. This class * may decorate the {@link Request} and {@link AsyncHandler} * * @param fc {@link FilterContext} * @return {@link FilterContext} */ private <T> FilterContext<T> preProcessRequest(FilterContext<T> fc) throws FilterException { for (RequestFilter asyncFilter : config.getRequestFilters()) { fc = asyncFilter.filter(fc); assertNotNull(fc, "filterContext"); } Request request = fc.getRequest(); if (fc.getAsyncHandler() instanceof ResumableAsyncHandler) { request = ResumableAsyncHandler.class.cast(fc.getAsyncHandler()).adjustRequestRange(request); } if (request.getRangeOffset() != 0) { RequestBuilder builder = new RequestBuilder(request); builder.setHeader("Range", "bytes=" + request.getRangeOffset() + "-"); request = builder.build(); } fc = new FilterContext.FilterContextBuilder<>(fc).request(request).build(); return fc; }
public <T> FilterContext<T> filter(FilterContext<T> ctx) throws FilterException { if (ctx.getIOException() != null && ctx.getAsyncHandler() instanceof ResumableAsyncHandler) { Request request = ResumableAsyncHandler.class.cast(ctx.getAsyncHandler()).adjustRequestRange(ctx.getRequest()); return new FilterContext.FilterContextBuilder<>(ctx).request(request).replayRequest(true).build(); } return ctx; } }
@Test public void testOnStatusReceivedOkStatus() throws Exception { MapResumableProcessor processor = new MapResumableProcessor(); ResumableAsyncHandler handler = new ResumableAsyncHandler(processor); HttpResponseStatus responseStatus200 = mock(HttpResponseStatus.class); when(responseStatus200.getStatusCode()).thenReturn(200); when(responseStatus200.getUri()).thenReturn(mock(Uri.class)); State state = handler.onStatusReceived(responseStatus200); assertEquals(state, AsyncHandler.State.CONTINUE, "Status should be CONTINUE for a OK response"); }
@Test public void testOnHeadersReceivedContentLengthMinus() throws Exception { ResumableAsyncHandler handler = new ResumableAsyncHandler(); HttpHeaders responseHeaders = new DefaultHttpHeaders(); responseHeaders.add(CONTENT_LENGTH, -1); State status = handler.onHeadersReceived(responseHeaders); assertEquals(status, AsyncHandler.State.ABORT, "State should be ABORT for content length -1"); } }
/** * Configure and execute the associated {@link RequestFilter}. This class may decorate the {@link Request} and {@link AsyncHandler} * * @param fc {@link FilterContext} * @return {@link FilterContext} */ private <T> FilterContext<T> preProcessRequest(FilterContext<T> fc) throws FilterException { for (RequestFilter asyncFilter : config.getRequestFilters()) { fc = asyncFilter.filter(fc); if (fc == null) { throw new NullPointerException("FilterContext is null"); } } Request request = fc.getRequest(); if (fc.getAsyncHandler() instanceof ResumableAsyncHandler) { request = ResumableAsyncHandler.class.cast(fc.getAsyncHandler()).adjustRequestRange(request); } if (request.getRangeOffset() != 0) { RequestBuilder builder = new RequestBuilder(request); builder.setHeader("Range", "bytes=" + request.getRangeOffset() + "-"); request = builder.build(); } fc = new FilterContext.FilterContextBuilder<>(fc).request(request).build(); return fc; }
@Test public void testOnStatusReceived206Status() throws Exception { MapResumableProcessor processor = new MapResumableProcessor(); ResumableAsyncHandler handler = new ResumableAsyncHandler(processor); HttpResponseStatus responseStatus206 = mock(HttpResponseStatus.class); when(responseStatus206.getStatusCode()).thenReturn(206); when(responseStatus206.getUri()).thenReturn(mock(Uri.class)); State state = handler.onStatusReceived(responseStatus206); assertEquals(state, AsyncHandler.State.CONTINUE, "Status should be CONTINUE for a 'Partial Content' response"); }
@Test public void testOnHeadersReceivedWithDecoratedAsyncHandler() throws Exception { HttpHeaders responseHeaders = new DefaultHttpHeaders(); @SuppressWarnings("unchecked") AsyncHandler<Response> decoratedAsyncHandler = mock(AsyncHandler.class); when(decoratedAsyncHandler.onHeadersReceived(responseHeaders)).thenReturn(State.CONTINUE); ResumableAsyncHandler handler = new ResumableAsyncHandler(decoratedAsyncHandler); State status = handler.onHeadersReceived(responseHeaders); assertEquals(status, State.CONTINUE, "State should be equal to the state returned from decoratedAsyncHandler"); }
@Test public void testOnStatusReceivedOkStatusWithDecoratedAsyncHandler() throws Exception { HttpResponseStatus mockResponseStatus = mock(HttpResponseStatus.class); when(mockResponseStatus.getStatusCode()).thenReturn(200); when(mockResponseStatus.getUri()).thenReturn(mock(Uri.class)); @SuppressWarnings("unchecked") AsyncHandler<Response> decoratedAsyncHandler = mock(AsyncHandler.class); when(decoratedAsyncHandler.onStatusReceived(mockResponseStatus)).thenReturn(State.CONTINUE); ResumableAsyncHandler handler = new ResumableAsyncHandler(decoratedAsyncHandler); State state = handler.onStatusReceived(mockResponseStatus); verify(decoratedAsyncHandler).onStatusReceived(mockResponseStatus); assertEquals(state, State.CONTINUE, "State returned should be equal to the one returned from decoratedAsyncHandler"); }