Search in sources :

Example 1 with RetryPolicy

use of com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy in project styx by ExpediaGroup.

the class StyxBackendServiceClientTest method retriesWhenRetryPolicyTellsToRetry.

@Test
public void retriesWhenRetryPolicyTellsToRetry() {
    RetryPolicy retryPolicy = mockRetryPolicy(true, false);
    StyxHostHttpClient firstClient = mockHostClient(Flux.error(new OriginUnreachableException(ORIGIN_1, new RuntimeException("An error occurred"))));
    StyxHostHttpClient secondClient = mockHostClient(Flux.just(response(OK).build()));
    StyxBackendServiceClient styxHttpClient = new StyxBackendServiceClient.Builder(backendService.id()).metrics(metrics).loadBalancer(mockLoadBalancer(Optional.of(remoteHost(ORIGIN_1, toHandler(firstClient), firstClient)), Optional.of(remoteHost(ORIGIN_2, toHandler(secondClient), secondClient)))).retryPolicy(retryPolicy).build();
    LiveHttpResponse response = Mono.from(styxHttpClient.sendRequest(SOME_REQ, requestContext())).block();
    ArgumentCaptor<RetryPolicy.Context> retryContext = ArgumentCaptor.forClass(RetryPolicy.Context.class);
    ArgumentCaptor<LoadBalancer> lbPreference = ArgumentCaptor.forClass(LoadBalancer.class);
    ArgumentCaptor<LoadBalancer.Preferences> lbContext = ArgumentCaptor.forClass(LoadBalancer.Preferences.class);
    verify(retryPolicy).evaluate(retryContext.capture(), lbPreference.capture(), lbContext.capture());
    assertThat(retryContext.getValue().appId(), is(backendService.id()));
    assertThat(retryContext.getValue().currentRetryCount(), is(1));
    assertThat(retryContext.getValue().lastException().get(), Matchers.instanceOf(OriginUnreachableException.class));
    assertThat(lbPreference.getValue(), notNullValue());
    assertThat(lbContext.getValue().preferredOrigins(), is(Optional.empty()));
    assertThat(lbContext.getValue().avoidOrigins(), is(asList(ORIGIN_1)));
    assertThat(response.status(), is(OK));
    InOrder ordered = inOrder(firstClient, secondClient);
    ordered.verify(firstClient).sendRequest(eq(SOME_REQ), any(Context.class));
    ordered.verify(secondClient).sendRequest(eq(SOME_REQ), any(Context.class));
}
Also used : Support.requestContext(com.hotels.styx.support.Support.requestContext) Context(com.hotels.styx.api.HttpInterceptor.Context) OriginUnreachableException(com.hotels.styx.api.exceptions.OriginUnreachableException) InOrder(org.mockito.InOrder) Origin.newOriginBuilder(com.hotels.styx.api.extension.Origin.newOriginBuilder) LoadBalancer(com.hotels.styx.api.extension.loadbalancing.spi.LoadBalancer) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) RetryPolicy(com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy) Test(org.junit.jupiter.api.Test)

Example 2 with RetryPolicy

use of com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy in project styx by ExpediaGroup.

the class StyxBackendServiceClientTest method constructsRetryContextWhenLoadBalancerDoesNotFindAvailableOrigins.

@Test
public void constructsRetryContextWhenLoadBalancerDoesNotFindAvailableOrigins() {
    RetryPolicy retryPolicy = mockRetryPolicy(true, true, true);
    StyxHostHttpClient hostClient = mockHostClient(Flux.just(response(OK).build()));
    StyxBackendServiceClient styxHttpClient = new StyxBackendServiceClient.Builder(backendService.id()).metrics(metrics).loadBalancer(mockLoadBalancer(Optional.empty(), Optional.of(remoteHost(SOME_ORIGIN, toHandler(hostClient), hostClient)))).retryPolicy(retryPolicy).build();
    LiveHttpResponse response = Mono.from(styxHttpClient.sendRequest(SOME_REQ, requestContext())).block();
    ArgumentCaptor<RetryPolicy.Context> retryContext = ArgumentCaptor.forClass(RetryPolicy.Context.class);
    ArgumentCaptor<LoadBalancer> lbPreference = ArgumentCaptor.forClass(LoadBalancer.class);
    ArgumentCaptor<LoadBalancer.Preferences> lbContext = ArgumentCaptor.forClass(LoadBalancer.Preferences.class);
    verify(retryPolicy).evaluate(retryContext.capture(), lbPreference.capture(), lbContext.capture());
    assertThat(retryContext.getValue().appId(), is(backendService.id()));
    assertThat(retryContext.getValue().currentRetryCount(), is(1));
    assertThat(retryContext.getValue().lastException(), is(Optional.empty()));
    assertThat(lbPreference.getValue(), notNullValue());
    assertThat(lbContext.getValue().avoidOrigins(), is(empty()));
    assertThat(lbContext.getValue().preferredOrigins(), is(Optional.empty()));
    assertThat(response.status(), is(OK));
}
Also used : Support.requestContext(com.hotels.styx.support.Support.requestContext) Context(com.hotels.styx.api.HttpInterceptor.Context) Origin.newOriginBuilder(com.hotels.styx.api.extension.Origin.newOriginBuilder) LoadBalancer(com.hotels.styx.api.extension.loadbalancing.spi.LoadBalancer) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) RetryPolicy(com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy) Test(org.junit.jupiter.api.Test)

Example 3 with RetryPolicy

use of com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy in project styx by ExpediaGroup.

the class StyxBackendServiceClientTest method updatedRequestWithUpdatedHostHeaderIsPresentInResponseWhenOverrideHostHeaderIsTrue.

@Test
public void updatedRequestWithUpdatedHostHeaderIsPresentInResponseWhenOverrideHostHeaderIsTrue() {
    HttpInterceptor.Context requestContext = requestContext();
    StyxHostHttpClient hostClient = mock(StyxHostHttpClient.class);
    HttpHandler httpHandler = mock(HttpHandler.class);
    Origin origin = newOriginBuilder(updatedHostName, 9090).applicationId(GENERIC_APP).build();
    RemoteHost remoteHost = remoteHost(origin, httpHandler, hostClient);
    LoadBalancer loadBalancer = mockLoadBalancer(Optional.of(remoteHost));
    when(httpHandler.handle(any(), any())).thenReturn(Eventual.of(testResponse));
    StyxBackendServiceClient styxHttpClient = new StyxBackendServiceClient.Builder(backendService.id()).originStatsFactory(mock(OriginStatsFactory.class)).originsRestrictionCookieName("someCookie").originIdHeader("origin-id").loadBalancer(loadBalancer).retryPolicy(new RetryNTimes(0)).metrics(metrics).overrideHostHeader(true).build();
    Publisher<LiveHttpResponse> responsePublisher = styxHttpClient.sendRequest(testRequest, requestContext);
    StepVerifier.create(responsePublisher).expectNextMatches(it -> it.request().header(HttpHeaderNames.HOST).isPresent() && it.request().header(HttpHeaderNames.HOST).get().equals(updatedHostName)).verifyComplete();
}
Also used : Origin(com.hotels.styx.api.extension.Origin) RetryNTimes(com.hotels.styx.client.retry.RetryNTimes) BeforeEach(org.junit.jupiter.api.BeforeEach) SimpleMeterRegistry(io.micrometer.core.instrument.simple.SimpleMeterRegistry) StepVerifier(reactor.test.StepVerifier) LiveHttpResponse.response(com.hotels.styx.api.LiveHttpResponse.response) Processor(org.reactivestreams.Processor) Origin.newOriginBuilder(com.hotels.styx.api.extension.Origin.newOriginBuilder) RemoteHost.remoteHost(com.hotels.styx.api.extension.RemoteHost.remoteHost) Support.requestContext(com.hotels.styx.support.Support.requestContext) Context(com.hotels.styx.api.HttpInterceptor.Context) Arrays.asList(java.util.Arrays.asList) Matchers.eq(org.mockito.Matchers.eq) StickySessionConfig.stickySessionDisabled(com.hotels.styx.api.extension.service.StickySessionConfig.stickySessionDisabled) LiveHttpRequest.get(com.hotels.styx.api.LiveHttpRequest.get) MicrometerRegistry(com.hotels.styx.api.MicrometerRegistry) BAD_REQUEST(com.hotels.styx.api.HttpResponseStatus.BAD_REQUEST) HttpHandler(com.hotels.styx.api.HttpHandler) OriginUnreachableException(com.hotels.styx.api.exceptions.OriginUnreachableException) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) HttpHeaderNames(com.hotels.styx.api.HttpHeaderNames) LoadBalancer(com.hotels.styx.api.extension.loadbalancing.spi.LoadBalancer) Test(org.junit.jupiter.api.Test) Matchers.any(org.mockito.Matchers.any) CHUNKED(com.hotels.styx.api.HttpHeaderNames.CHUNKED) CONTENT_LENGTH(com.hotels.styx.api.HttpHeaderNames.CONTENT_LENGTH) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Mockito.inOrder(org.mockito.Mockito.inOrder) Origin(com.hotels.styx.api.extension.Origin) Optional(java.util.Optional) Matchers.is(org.hamcrest.Matchers.is) RequestCookie.requestCookie(com.hotels.styx.api.RequestCookie.requestCookie) Arrays.stream(java.util.Arrays.stream) Mockito.mock(org.mockito.Mockito.mock) RetryPolicy(com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy) GENERIC_APP(com.hotels.styx.api.Id.GENERIC_APP) StickySessionConfig(com.hotels.styx.api.extension.service.StickySessionConfig) NOT_IMPLEMENTED(com.hotels.styx.api.HttpResponseStatus.NOT_IMPLEMENTED) UNAUTHORIZED(com.hotels.styx.api.HttpResponseStatus.UNAUTHORIZED) TRANSFER_ENCODING(com.hotels.styx.api.HttpHeaderNames.TRANSFER_ENCODING) ArgumentCaptor(org.mockito.ArgumentCaptor) RetryNTimes(com.hotels.styx.client.retry.RetryNTimes) NoAvailableHostsException(com.hotels.styx.api.exceptions.NoAvailableHostsException) EmitterProcessor(reactor.core.publisher.EmitterProcessor) BackendService(com.hotels.styx.api.extension.service.BackendService) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Eventual(com.hotels.styx.api.Eventual) Matchers.empty(org.hamcrest.Matchers.empty) InOrder(org.mockito.InOrder) INTERNAL_SERVER_ERROR(com.hotels.styx.api.HttpResponseStatus.INTERNAL_SERVER_ERROR) Publisher(org.reactivestreams.Publisher) Matchers(org.hamcrest.Matchers) Mono(reactor.core.publisher.Mono) Mockito.when(org.mockito.Mockito.when) HostAndPort(com.google.common.net.HostAndPort) HttpResponseStatus(com.hotels.styx.api.HttpResponseStatus) RemoteHost(com.hotels.styx.api.extension.RemoteHost) Mockito.verify(org.mockito.Mockito.verify) HttpInterceptor(com.hotels.styx.api.HttpInterceptor) Flux(reactor.core.publisher.Flux) Mockito.never(org.mockito.Mockito.never) MeterRegistry(com.hotels.styx.api.MeterRegistry) OK(com.hotels.styx.api.HttpResponseStatus.OK) CentralisedMetrics(com.hotels.styx.metrics.CentralisedMetrics) Id(com.hotels.styx.api.Id) LiveHttpRequest(com.hotels.styx.api.LiveHttpRequest) HttpHandler(com.hotels.styx.api.HttpHandler) Origin.newOriginBuilder(com.hotels.styx.api.extension.Origin.newOriginBuilder) LoadBalancer(com.hotels.styx.api.extension.loadbalancing.spi.LoadBalancer) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Context(com.hotels.styx.api.HttpInterceptor.Context) RemoteHost(com.hotels.styx.api.extension.RemoteHost) HttpInterceptor(com.hotels.styx.api.HttpInterceptor) Test(org.junit.jupiter.api.Test)

Example 4 with RetryPolicy

use of com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy in project styx by ExpediaGroup.

the class StyxBackendServiceClientTest method originalRequestIsPresentInResponseWhenOverrideHostHeaderIsFalse.

@Test
public void originalRequestIsPresentInResponseWhenOverrideHostHeaderIsFalse() {
    HttpInterceptor.Context requestContext = requestContext();
    StyxHostHttpClient hostClient = mock(StyxHostHttpClient.class);
    HttpHandler httpHandler = mock(HttpHandler.class);
    Origin origin = newOriginBuilder(incomingHostname, 9090).applicationId(GENERIC_APP).build();
    RemoteHost remoteHost = remoteHost(origin, httpHandler, hostClient);
    LoadBalancer loadBalancer = mockLoadBalancer(Optional.of(remoteHost));
    when(httpHandler.handle(any(), any())).thenReturn(Eventual.of(testResponse));
    StyxBackendServiceClient styxHttpClient = new StyxBackendServiceClient.Builder(backendService.id()).originStatsFactory(mock(OriginStatsFactory.class)).originsRestrictionCookieName("someCookie").originIdHeader("origin-id").loadBalancer(loadBalancer).retryPolicy(new RetryNTimes(0)).metrics(metrics).overrideHostHeader(false).build();
    Publisher<LiveHttpResponse> responsePublisher = styxHttpClient.sendRequest(testRequest, requestContext);
    StepVerifier.create(responsePublisher).expectNextMatches(it -> it.request().header(HttpHeaderNames.HOST).isPresent() && it.request().header(HttpHeaderNames.HOST).get().equals(incomingHostname)).verifyComplete();
}
Also used : Origin(com.hotels.styx.api.extension.Origin) RetryNTimes(com.hotels.styx.client.retry.RetryNTimes) BeforeEach(org.junit.jupiter.api.BeforeEach) SimpleMeterRegistry(io.micrometer.core.instrument.simple.SimpleMeterRegistry) StepVerifier(reactor.test.StepVerifier) LiveHttpResponse.response(com.hotels.styx.api.LiveHttpResponse.response) Processor(org.reactivestreams.Processor) Origin.newOriginBuilder(com.hotels.styx.api.extension.Origin.newOriginBuilder) RemoteHost.remoteHost(com.hotels.styx.api.extension.RemoteHost.remoteHost) Support.requestContext(com.hotels.styx.support.Support.requestContext) Context(com.hotels.styx.api.HttpInterceptor.Context) Arrays.asList(java.util.Arrays.asList) Matchers.eq(org.mockito.Matchers.eq) StickySessionConfig.stickySessionDisabled(com.hotels.styx.api.extension.service.StickySessionConfig.stickySessionDisabled) LiveHttpRequest.get(com.hotels.styx.api.LiveHttpRequest.get) MicrometerRegistry(com.hotels.styx.api.MicrometerRegistry) BAD_REQUEST(com.hotels.styx.api.HttpResponseStatus.BAD_REQUEST) HttpHandler(com.hotels.styx.api.HttpHandler) OriginUnreachableException(com.hotels.styx.api.exceptions.OriginUnreachableException) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) HttpHeaderNames(com.hotels.styx.api.HttpHeaderNames) LoadBalancer(com.hotels.styx.api.extension.loadbalancing.spi.LoadBalancer) Test(org.junit.jupiter.api.Test) Matchers.any(org.mockito.Matchers.any) CHUNKED(com.hotels.styx.api.HttpHeaderNames.CHUNKED) CONTENT_LENGTH(com.hotels.styx.api.HttpHeaderNames.CONTENT_LENGTH) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Mockito.inOrder(org.mockito.Mockito.inOrder) Origin(com.hotels.styx.api.extension.Origin) Optional(java.util.Optional) Matchers.is(org.hamcrest.Matchers.is) RequestCookie.requestCookie(com.hotels.styx.api.RequestCookie.requestCookie) Arrays.stream(java.util.Arrays.stream) Mockito.mock(org.mockito.Mockito.mock) RetryPolicy(com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy) GENERIC_APP(com.hotels.styx.api.Id.GENERIC_APP) StickySessionConfig(com.hotels.styx.api.extension.service.StickySessionConfig) NOT_IMPLEMENTED(com.hotels.styx.api.HttpResponseStatus.NOT_IMPLEMENTED) UNAUTHORIZED(com.hotels.styx.api.HttpResponseStatus.UNAUTHORIZED) TRANSFER_ENCODING(com.hotels.styx.api.HttpHeaderNames.TRANSFER_ENCODING) ArgumentCaptor(org.mockito.ArgumentCaptor) RetryNTimes(com.hotels.styx.client.retry.RetryNTimes) NoAvailableHostsException(com.hotels.styx.api.exceptions.NoAvailableHostsException) EmitterProcessor(reactor.core.publisher.EmitterProcessor) BackendService(com.hotels.styx.api.extension.service.BackendService) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Eventual(com.hotels.styx.api.Eventual) Matchers.empty(org.hamcrest.Matchers.empty) InOrder(org.mockito.InOrder) INTERNAL_SERVER_ERROR(com.hotels.styx.api.HttpResponseStatus.INTERNAL_SERVER_ERROR) Publisher(org.reactivestreams.Publisher) Matchers(org.hamcrest.Matchers) Mono(reactor.core.publisher.Mono) Mockito.when(org.mockito.Mockito.when) HostAndPort(com.google.common.net.HostAndPort) HttpResponseStatus(com.hotels.styx.api.HttpResponseStatus) RemoteHost(com.hotels.styx.api.extension.RemoteHost) Mockito.verify(org.mockito.Mockito.verify) HttpInterceptor(com.hotels.styx.api.HttpInterceptor) Flux(reactor.core.publisher.Flux) Mockito.never(org.mockito.Mockito.never) MeterRegistry(com.hotels.styx.api.MeterRegistry) OK(com.hotels.styx.api.HttpResponseStatus.OK) CentralisedMetrics(com.hotels.styx.metrics.CentralisedMetrics) Id(com.hotels.styx.api.Id) LiveHttpRequest(com.hotels.styx.api.LiveHttpRequest) HttpHandler(com.hotels.styx.api.HttpHandler) Origin.newOriginBuilder(com.hotels.styx.api.extension.Origin.newOriginBuilder) LoadBalancer(com.hotels.styx.api.extension.loadbalancing.spi.LoadBalancer) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Context(com.hotels.styx.api.HttpInterceptor.Context) RemoteHost(com.hotels.styx.api.extension.RemoteHost) HttpInterceptor(com.hotels.styx.api.HttpInterceptor) Test(org.junit.jupiter.api.Test)

Example 5 with RetryPolicy

use of com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy in project styx by ExpediaGroup.

the class RetryPolicyFactoryTest method usesDefaultCountOf1IfNotSpecified.

@Test
public void usesDefaultCountOf1IfNotSpecified() {
    RetryPolicy retryPolicy = new RetryPolicyFactory().create(environment, EMPTY_CONFIGURATION);
    assertThat(retryPolicy, is(instanceOf(RetryNTimes.class)));
    assertThat(((RetryNTimes) retryPolicy).maxAttempts(), is(1));
}
Also used : RetryPolicy(com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy) Test(org.junit.jupiter.api.Test)

Aggregations

RetryPolicy (com.hotels.styx.api.extension.retrypolicy.spi.RetryPolicy)7 Test (org.junit.jupiter.api.Test)7 Context (com.hotels.styx.api.HttpInterceptor.Context)5 LiveHttpResponse (com.hotels.styx.api.LiveHttpResponse)5 Origin.newOriginBuilder (com.hotels.styx.api.extension.Origin.newOriginBuilder)5 LoadBalancer (com.hotels.styx.api.extension.loadbalancing.spi.LoadBalancer)5 OriginUnreachableException (com.hotels.styx.api.exceptions.OriginUnreachableException)4 Support.requestContext (com.hotels.styx.support.Support.requestContext)4 HostAndPort (com.google.common.net.HostAndPort)3 Eventual (com.hotels.styx.api.Eventual)3 HttpHandler (com.hotels.styx.api.HttpHandler)3 HttpHeaderNames (com.hotels.styx.api.HttpHeaderNames)3 CHUNKED (com.hotels.styx.api.HttpHeaderNames.CHUNKED)3 CONTENT_LENGTH (com.hotels.styx.api.HttpHeaderNames.CONTENT_LENGTH)3 TRANSFER_ENCODING (com.hotels.styx.api.HttpHeaderNames.TRANSFER_ENCODING)3 HttpInterceptor (com.hotels.styx.api.HttpInterceptor)3 HttpResponseStatus (com.hotels.styx.api.HttpResponseStatus)3 BAD_REQUEST (com.hotels.styx.api.HttpResponseStatus.BAD_REQUEST)3 INTERNAL_SERVER_ERROR (com.hotels.styx.api.HttpResponseStatus.INTERNAL_SERVER_ERROR)3 NOT_IMPLEMENTED (com.hotels.styx.api.HttpResponseStatus.NOT_IMPLEMENTED)3