public HttpResponseImpl response() throws IOException, InterruptedException { HttpRequestImpl r = request; if (r.timeval() != 0) { // set timer td = new TimedEvent(r.timeval()); client.registerTimer(td); } while (attempts < max_attempts) { try { attempts++; Exchange currExchange = getExchange(); requestFilters(r); HttpResponseImpl response = currExchange.response(); Pair<HttpResponse, HttpRequestImpl> filterResult = responseFilters(response); HttpRequestImpl newreq = filterResult.second; if (newreq == null) { if (attempts > 1) { Log.logError("Succeeded on attempt: " + attempts); } cancelTimer(); return response; } response.body(HttpResponse.ignoreBody()); setExchange(new Exchange(newreq, currExchange.getAccessControlContext())); r = newreq; } catch (IOException e) { if (cancelled) { throw new HttpTimeoutException("Request timed out"); } throw e; } } cancelTimer(); throw new IOException("Retry limit exceeded"); }
public CompletableFuture<HttpResponseImpl> responseAsync(Void v) { CompletableFuture<HttpResponseImpl> cf; if (++attempts > max_attempts) { cf = CompletableFuture.failedFuture(new IOException("Too many retries")); } else { if (currentreq.timeval() != 0) { // set timer td = new TimedEvent(currentreq.timeval()); client.registerTimer(td); } Exchange exch = getExchange(); cf = requestFiltersAsync(currentreq) .thenCompose(exch::responseAsync) .thenCompose(this::responseFiltersAsync) .thenCompose( (Pair<HttpResponse, HttpRequestImpl> pair) -> { HttpResponseImpl resp = (HttpResponseImpl) pair.first; if (resp != null) { if (attempts > 1) { Log.logError("Succeeded on attempt: " + attempts); } return CompletableFuture.completedFuture(resp); } else { currentreq = pair.second; Exchange previous = exch; setExchange(new Exchange(currentreq, currentreq.getAccessControlContext())); // reads body off previous, and then waits for next response return previous .responseBodyAsync(HttpResponse.ignoreBody()) .thenCompose(this::responseAsync); } }) .handle( (BiFunction<HttpResponse, Throwable, Pair<HttpResponse, Throwable>>) Pair::new) .thenCompose( (Pair<HttpResponse, Throwable> obj) -> { HttpResponseImpl response = (HttpResponseImpl) obj.first; if (response != null) { return CompletableFuture.completedFuture(response); } // all exceptions thrown are handled here CompletableFuture<HttpResponseImpl> error = getExceptionalCF(obj.second); if (error == null) { cancelTimer(); return responseAsync(null); } else { return error; } }); } return cf; }
@Override public void onMessage(final HttpRequest request, final HttpResponse response) throws Exception { HttpRequestImpl req = null; if (request instanceof HttpRequestImpl) { req = (HttpRequestImpl) request; } else if (request instanceof ServletRequestAdapter) { final HttpServletRequest delegate = ((ServletRequestAdapter) request).getRequest(); if (delegate instanceof HttpRequestImpl) { req = (HttpRequestImpl) delegate; } } if (req != null) { req.initPathFromContext((!context.startsWith("/") ? "/" : "") + context); } delegate.doFilter(request, response, new SimpleFilterChain(this)); }
@Test public void testSetAndGetResponseExactMatchAddedParameters() throws UnsatisfiedExpectationException { httpResponseProviderIgnoreAdditionalHeaders = new DefaultHttpResponseProvider(false); httpResponseProviderIgnoreAdditionalHeaders.set(httpRequest, httpResponse); final HttpRequestImpl requestWithAdditionalParam = new HttpRequestImpl(httpRequest); requestWithAdditionalParam.httpMessageHeader("param2", "value2"); assertNull( "Additional header param should not be ignored.", httpResponseProviderIgnoreAdditionalHeaders.getResponse(requestWithAdditionalParam)); expectVerifyToFail( httpResponseProviderIgnoreAdditionalHeaders, httpRequest, requestWithAdditionalParam); }
@Test public void testSetAndGetResponseIgnoreAdditionalHeadersOtherMethod() throws UnsatisfiedExpectationException { httpResponseProviderIgnoreAdditionalHeaders = new DefaultHttpResponseProvider(true); httpResponseProviderIgnoreAdditionalHeaders.set(httpRequest, httpResponse); final HttpRequestImpl requestWithOtherMethod = new HttpRequestImpl(httpRequest); requestWithOtherMethod.method(Method.POST); assertNull( "Other method should not be ignored.", httpResponseProviderIgnoreAdditionalHeaders.getResponse(requestWithOtherMethod)); expectVerifyToFail( httpResponseProviderIgnoreAdditionalHeaders, httpRequest, requestWithOtherMethod); }
@Test public void testSetAndGetResponseIgnoreAdditionalHeadersAddedParameters() throws UnsatisfiedExpectationException { httpResponseProviderIgnoreAdditionalHeaders = new DefaultHttpResponseProvider(true); httpResponseProviderIgnoreAdditionalHeaders.set(httpRequest, httpResponse); final HttpRequestImpl requestWithAdditionalParam = new HttpRequestImpl(httpRequest); requestWithAdditionalParam.httpMessageHeader("param2", "value2"); assertSame( "Additional header param should be ignored.", httpResponse, httpResponseProviderIgnoreAdditionalHeaders.getResponse(requestWithAdditionalParam)); httpResponseProviderIgnoreAdditionalHeaders.verify(); // Expect no exception. }
@Test public void testSetAndGetResponseIgnoreAdditionalHeadersOtherContent() throws UnsatisfiedExpectationException { httpResponseProviderIgnoreAdditionalHeaders = new DefaultHttpResponseProvider(true); httpResponseProviderIgnoreAdditionalHeaders.set(httpRequest, httpResponse); final HttpRequestImpl requestWithOtherContent = new HttpRequestImpl(httpRequest); requestWithOtherContent.content(new String("content").getBytes()); assertNull( "Other content should not be ignored.", httpResponseProviderIgnoreAdditionalHeaders.getResponse(requestWithOtherContent)); expectVerifyToFail( httpResponseProviderIgnoreAdditionalHeaders, httpRequest, requestWithOtherContent); }
@Test public void testSetAndGetResponseIgnoreAdditionalHeadersOtherQueryParamValue() throws UnsatisfiedExpectationException { httpResponseProviderIgnoreAdditionalHeaders = new DefaultHttpResponseProvider(true); httpResponseProviderIgnoreAdditionalHeaders.set(httpRequest, httpResponse); final HttpRequestImpl requestWithOtherQueryParam = new HttpRequestImpl(httpRequest); requestWithOtherQueryParam.queryParameter(QUERY_PARAM, "other value"); assertNull( "Other query param value for a query param that was set in original request should not be ignored.", httpResponseProviderIgnoreAdditionalHeaders.getResponse(requestWithOtherQueryParam)); expectVerifyToFail( httpResponseProviderIgnoreAdditionalHeaders, httpRequest, requestWithOtherQueryParam); }
MultiExchange(HttpRequestImpl request) { this.exchange = new Exchange(request); this.previous = null; this.request = request; this.currentreq = request; this.attempts = 0; this.client = request.client(); this.filters = client.filterChain(); }
@Test public void testReset() throws UnsatisfiedExpectationException { httpResponseProviderIgnoreAdditionalHeaders = new DefaultHttpResponseProvider(false); httpResponseProviderIgnoreAdditionalHeaders.set(httpRequest, httpResponse); httpResponseProviderIgnoreAdditionalHeaders.reset(); final HttpRequestImpl requestWithAdditionalParam = new HttpRequestImpl(httpRequest); requestWithAdditionalParam.httpMessageHeader("param2", "value2"); httpResponseProviderIgnoreAdditionalHeaders.set(requestWithAdditionalParam, httpResponse); assertSame( httpResponse, httpResponseProviderIgnoreAdditionalHeaders.getResponse(requestWithAdditionalParam)); httpResponseProviderIgnoreAdditionalHeaders.verify(); }
@Before public void setup() { httpResponseProviderIgnoreAdditionalHeaders = new DefaultHttpResponseProvider(true); httpRequest = new HttpRequestImpl(); httpRequest .method(METHOD) .path(PATH) .httpMessageHeader(HttpMessageHeaderField.CONTENTTYPE.getValue(), CONTENT_TYPE) .queryParameter(QUERY_PARAM, QUERY_PARAM_VALUE); httpResponse = new HttpResponseImpl(HTTP_CODE, null, null); }