Search in sources :

Example 1 with TransportException

use of com.netflix.discovery.shared.transport.TransportException in project eureka by Netflix.

the class RetryableEurekaHttpClient method execute.

@Override
protected <R> EurekaHttpResponse<R> execute(RequestExecutor<R> requestExecutor) {
    List<EurekaEndpoint> candidateHosts = null;
    int endpointIdx = 0;
    for (int retry = 0; retry < numberOfRetries; retry++) {
        EurekaHttpClient currentHttpClient = delegate.get();
        EurekaEndpoint currentEndpoint = null;
        if (currentHttpClient == null) {
            if (candidateHosts == null) {
                candidateHosts = getHostCandidates();
                if (candidateHosts.isEmpty()) {
                    throw new TransportException("There is no known eureka server; cluster server list is empty");
                }
            }
            if (endpointIdx >= candidateHosts.size()) {
                throw new TransportException("Cannot execute request on any known server");
            }
            currentEndpoint = candidateHosts.get(endpointIdx++);
            currentHttpClient = clientFactory.newClient(currentEndpoint);
        }
        try {
            EurekaHttpResponse<R> response = requestExecutor.execute(currentHttpClient);
            if (serverStatusEvaluator.accept(response.getStatusCode(), requestExecutor.getRequestType())) {
                delegate.set(currentHttpClient);
                if (retry > 0) {
                    logger.info("Request execution succeeded on retry #{}", retry);
                }
                return response;
            }
            logger.warn("Request execution failure with status code {}; retrying on another server if available", response.getStatusCode());
        } catch (Exception e) {
            // just log message as the underlying client should log the stacktrace
            logger.warn("Request execution failed with message: {}", e.getMessage());
        }
        // Connection error or 5xx from the server that must be retried on another server
        delegate.compareAndSet(currentHttpClient, null);
        if (currentEndpoint != null) {
            quarantineSet.add(currentEndpoint);
        }
    }
    throw new TransportException("Retry limit reached; giving up on completing the request");
}
Also used : EurekaHttpClient(com.netflix.discovery.shared.transport.EurekaHttpClient) TransportException(com.netflix.discovery.shared.transport.TransportException) EurekaEndpoint(com.netflix.discovery.shared.resolver.EurekaEndpoint) TransportException(com.netflix.discovery.shared.transport.TransportException) EurekaEndpoint(com.netflix.discovery.shared.resolver.EurekaEndpoint)

Example 2 with TransportException

use of com.netflix.discovery.shared.transport.TransportException in project eureka by Netflix.

the class RedirectingEurekaHttpClient method executeOnNewServer.

private <R> EurekaHttpResponse<R> executeOnNewServer(RequestExecutor<R> requestExecutor, AtomicReference<EurekaHttpClient> currentHttpClientRef) {
    URI targetUrl = null;
    for (int followRedirectCount = 0; followRedirectCount < MAX_FOLLOWED_REDIRECTS; followRedirectCount++) {
        EurekaHttpResponse<R> httpResponse = requestExecutor.execute(currentHttpClientRef.get());
        if (httpResponse.getStatusCode() != 302) {
            if (followRedirectCount == 0) {
                logger.debug("Pinning to endpoint {}", targetUrl);
            } else {
                logger.info("Pinning to endpoint {}, after {} redirect(s)", targetUrl, followRedirectCount);
            }
            return httpResponse;
        }
        targetUrl = getRedirectBaseUri(httpResponse.getLocation());
        if (targetUrl == null) {
            throw new TransportException("Invalid redirect URL " + httpResponse.getLocation());
        }
        currentHttpClientRef.getAndSet(null).shutdown();
        currentHttpClientRef.set(factory.newClient(new DefaultEndpoint(targetUrl.toString())));
    }
    String message = "Follow redirect limit crossed for URI " + serviceEndpoint.getServiceUrl();
    logger.warn(message);
    throw new TransportException(message);
}
Also used : DefaultEndpoint(com.netflix.discovery.shared.resolver.DefaultEndpoint) URI(java.net.URI) TransportException(com.netflix.discovery.shared.transport.TransportException) EurekaEndpoint(com.netflix.discovery.shared.resolver.EurekaEndpoint) DefaultEndpoint(com.netflix.discovery.shared.resolver.DefaultEndpoint)

Example 3 with TransportException

use of com.netflix.discovery.shared.transport.TransportException in project eureka by Netflix.

the class RedirectingEurekaHttpClientTest method testOnConnectionErrorPinnedClientIsDestroyed.

@Test
public void testOnConnectionErrorPinnedClientIsDestroyed() throws Exception {
    setupRedirect();
    RedirectingEurekaHttpClient httpClient = new RedirectingEurekaHttpClient(SERVICE_URL, factory, dnsService);
    // First call pins client to resolved IP
    httpClient.getApplications();
    verify(redirectedClient, times(1)).getApplications();
    // Trigger connection error
    when(redirectedClient.getApplications()).thenThrow(new TransportException("simulated network error"));
    try {
        httpClient.getApplications();
        fail("Expected transport error");
    } catch (Exception ignored) {
    }
    // Subsequent connection shall create new httpClient
    reset(factory, sourceClient, dnsService, redirectedClient);
    setupRedirect();
    httpClient.getApplications();
    verify(factory, times(2)).newClient(Matchers.<EurekaEndpoint>anyVararg());
    verify(sourceClient, times(1)).getApplications();
    verify(dnsService, times(1)).resolveIp("another.discovery.test");
    verify(redirectedClient, times(1)).getApplications();
}
Also used : TransportException(com.netflix.discovery.shared.transport.TransportException) TransportException(com.netflix.discovery.shared.transport.TransportException) Test(org.junit.Test)

Example 4 with TransportException

use of com.netflix.discovery.shared.transport.TransportException in project eureka by Netflix.

the class RedirectingEurekaHttpClient method getRedirectBaseUri.

private URI getRedirectBaseUri(URI locationURI) {
    if (locationURI == null) {
        throw new TransportException("Missing Location header in the redirect reply");
    }
    Matcher pathMatcher = REDIRECT_PATH_REGEX.matcher(locationURI.getPath());
    if (pathMatcher.matches()) {
        return UriBuilder.fromUri(locationURI).host(dnsService.resolveIp(locationURI.getHost())).replacePath(pathMatcher.group(1)).replaceQuery(null).build();
    }
    logger.warn("Invalid redirect URL {}", locationURI);
    return null;
}
Also used : Matcher(java.util.regex.Matcher) TransportException(com.netflix.discovery.shared.transport.TransportException)

Example 5 with TransportException

use of com.netflix.discovery.shared.transport.TransportException in project eureka by Netflix.

the class RetryableEurekaHttpClientTest method testRequestIsRetriedOnConnectionError.

@Test
public void testRequestIsRetriedOnConnectionError() throws Exception {
    when(clientFactory.newClient(Matchers.<EurekaEndpoint>anyVararg())).thenReturn(clusterDelegates.get(0), clusterDelegates.get(1));
    when(requestExecutor.execute(clusterDelegates.get(0))).thenThrow(new TransportException("simulated network error"));
    when(requestExecutor.execute(clusterDelegates.get(1))).thenReturn(EurekaHttpResponse.status(200));
    EurekaHttpResponse<Void> httpResponse = retryableClient.execute(requestExecutor);
    assertThat(httpResponse.getStatusCode(), is(equalTo(200)));
    verify(clientFactory, times(2)).newClient(Matchers.<EurekaEndpoint>anyVararg());
    verify(requestExecutor, times(1)).execute(clusterDelegates.get(0));
    verify(requestExecutor, times(1)).execute(clusterDelegates.get(1));
}
Also used : TransportException(com.netflix.discovery.shared.transport.TransportException) Test(org.junit.Test)

Aggregations

TransportException (com.netflix.discovery.shared.transport.TransportException)6 EurekaEndpoint (com.netflix.discovery.shared.resolver.EurekaEndpoint)3 Test (org.junit.Test)2 DefaultEndpoint (com.netflix.discovery.shared.resolver.DefaultEndpoint)1 AwsEndpoint (com.netflix.discovery.shared.resolver.aws.AwsEndpoint)1 EurekaHttpClient (com.netflix.discovery.shared.transport.EurekaHttpClient)1 URI (java.net.URI)1 Matcher (java.util.regex.Matcher)1