### Question:
InstanceExchangeFilterFunctions { public static ExchangeFilterFunction retry(int defaultRetries, Map<String, Integer> retriesPerEndpoint) { return (request, next) -> { int retries = 0; if (!request.method().equals(HttpMethod.DELETE) && !request.method().equals(HttpMethod.PATCH) && !request.method().equals(HttpMethod.POST) && !request.method().equals(HttpMethod.PUT)) { retries = request.attribute(ATTRIBUTE_ENDPOINT).map(retriesPerEndpoint::get).orElse(defaultRetries); } return next.exchange(request).retry(retries); }; } private  InstanceExchangeFilterFunctions(); static ExchangeFilterFunction setInstance(Instance instance); static ExchangeFilterFunction setInstance(Mono<Instance> instance); static ExchangeFilterFunction addHeaders(HttpHeadersProvider httpHeadersProvider); static ExchangeFilterFunction toExchangeFilterFunction(InstanceExchangeFilterFunction delegate); static ExchangeFilterFunction rewriteEndpointUrl(); static ExchangeFilterFunction convertLegacyEndpoint(LegacyEndpointConverter converter); static ExchangeFilterFunction setDefaultAcceptHeader(); static ExchangeFilterFunction retry(int defaultRetries, Map<String, Integer> retriesPerEndpoint); static final String ATTRIBUTE_INSTANCE; static final String ATTRIBUTE_ENDPOINT; }### Answer:
@Test public void should_retry_using_default() { ExchangeFilterFunction filter = InstanceExchangeFilterFunctions.retry(1, emptyMap()); ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test")).build(); ClientResponse response = mock(ClientResponse.class); AtomicLong invocationCount = new AtomicLong(0L); ExchangeFunction exchange = r -> Mono.fromSupplier(() -> { if (invocationCount.getAndIncrement() == 0) { throw new IllegalStateException("Test"); } return response; }); StepVerifier.create(filter.filter(request, exchange)).expectNext(response).verifyComplete(); assertThat(invocationCount.get()).isEqualTo(2); }
@Test public void should_retry_using_endpoint_value_default() { ExchangeFilterFunction filter = InstanceExchangeFilterFunctions.retry(0, singletonMap("test", 1)); ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test")) .attribute(ATTRIBUTE_ENDPOINT, "test") .build(); ClientResponse response = mock(ClientResponse.class); AtomicLong invocationCount = new AtomicLong(0L); ExchangeFunction exchange = r -> Mono.fromSupplier(() -> { if (invocationCount.getAndIncrement() == 0) { throw new IllegalStateException("Test"); } return response; }); StepVerifier.create(filter.filter(request, exchange)).expectNext(response).verifyComplete(); assertThat(invocationCount.get()).isEqualTo(2); }
@Test public void should_not_retry_for_put_post_patch_delete() { ExchangeFilterFunction filter = InstanceExchangeFilterFunctions.retry(1, emptyMap()); AtomicLong invocationCount = new AtomicLong(0L); ExchangeFunction exchange = r -> Mono.fromSupplier(() -> { invocationCount.incrementAndGet(); throw new IllegalStateException("Test"); }); ClientRequest patchRequest = ClientRequest.create(HttpMethod.PATCH, URI.create("/test")).build(); StepVerifier.create(filter.filter(patchRequest, exchange)).expectError(IllegalStateException.class).verify(); assertThat(invocationCount.get()).isEqualTo(1); invocationCount.set(0L); ClientRequest putRequest = ClientRequest.create(HttpMethod.PUT, URI.create("/test")).build(); StepVerifier.create(filter.filter(putRequest, exchange)).expectError(IllegalStateException.class).verify(); assertThat(invocationCount.get()).isEqualTo(1); invocationCount.set(0L); ClientRequest postRequest = ClientRequest.create(HttpMethod.POST, URI.create("/test")).build(); StepVerifier.create(filter.filter(postRequest, exchange)).expectError(IllegalStateException.class).verify(); assertThat(invocationCount.get()).isEqualTo(1); invocationCount.set(0L); ClientRequest deleteRequest = ClientRequest.create(HttpMethod.DELETE, URI.create("/test")).build(); StepVerifier.create(filter.filter(deleteRequest, exchange)).expectError(IllegalStateException.class).verify(); assertThat(invocationCount.get()).isEqualTo(1); }