Extract duplicate method to utility class.

This commit is contained in:
Olga Maciaszek-Sharma
2020-10-27 17:02:04 +01:00
parent 479e1ab743
commit 3f0c2850ee
3 changed files with 79 additions and 43 deletions

View File

@@ -42,6 +42,8 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;
import static org.springframework.cloud.openfeign.loadbalancer.LoadBalancerUtils.executeWithLoadBalancerLifecycleProcessing;
/**
* A {@link Client} implementation that uses {@link LoadBalancerClient} to select a
* {@link ServiceInstance} to use while resolving the request host.
@@ -100,25 +102,8 @@ public class FeignBlockingLoadBalancerClient implements Client {
String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri).toString();
Request newRequest = Request.create(request.httpMethod(), reconstructedUrl, request.headers(), request.body(),
request.charset(), request.requestTemplate());
return executeWithLoadBalancerLifecycleProcessing(options, supportedLifecycleProcessors, lbResponse,
newRequest);
}
private Response executeWithLoadBalancerLifecycleProcessing(Request.Options options,
Set<LoadBalancerLifecycle> supportedLifecycleProcessors,
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse, Request newRequest)
throws IOException {
try {
Response response = delegate.execute(newRequest, options);
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, lbResponse, response)));
return response;
}
catch (Exception exception) {
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbResponse)));
throw exception;
}
return executeWithLoadBalancerLifecycleProcessing(delegate, options, newRequest, lbResponse,
supportedLifecycleProcessors);
}
// Visible for Sleuth instrumentation

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2013-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.openfeign.loadbalancer;
import java.io.IOException;
import java.util.Set;
import feign.Client;
import feign.Request;
import feign.Response;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.CompletionContext;
import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle;
/**
* @author Olga Maciaszek-Sharma
*
* A utility class for handling {@link LoadBalancerLifecycle} calls.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
final class LoadBalancerUtils {
private LoadBalancerUtils() {
throw new IllegalStateException("Can't instantiate a utility class");
}
static Response executeWithLoadBalancerLifecycleProcessing(Client feignClient, Request.Options options,
Request feignRequest, org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse,
Set<LoadBalancerLifecycle> supportedLifecycleProcessors, boolean loadBalanced) throws IOException {
try {
Response response = feignClient.execute(feignRequest, options);
if (loadBalanced) {
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, lbResponse, response)));
}
return response;
}
catch (Exception exception) {
if (loadBalanced) {
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbResponse)));
}
throw exception;
}
}
static Response executeWithLoadBalancerLifecycleProcessing(Client feignClient, Request.Options options,
Request feignRequest, org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse,
Set<LoadBalancerLifecycle> supportedLifecycleProcessors) throws IOException {
return executeWithLoadBalancerLifecycleProcessing(feignClient, options, feignRequest, lbResponse,
supportedLifecycleProcessors, true);
}
}

View File

@@ -59,6 +59,8 @@ import org.springframework.retry.policy.NeverRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
import static org.springframework.cloud.openfeign.loadbalancer.LoadBalancerUtils.executeWithLoadBalancerLifecycleProcessing;
/**
* A {@link Client} implementation that provides Spring Retry support for requests
* load-balanced with Spring Cloud LoadBalancer.
@@ -150,8 +152,10 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
request.body(), request.charset(), request.requestTemplate());
}
}
Response response = executeWithLoadBalancerLifecycleProcessing(options, feignRequest,
retrievedServiceInstance, retrievedServiceInstance != null, supportedLifecycleProcessors);
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
retrievedServiceInstance);
Response response = executeWithLoadBalancerLifecycleProcessing(delegate, options, feignRequest, lbResponse,
supportedLifecycleProcessors, retrievedServiceInstance != null);
int responseStatus = response.status();
if (retryPolicy != null && retryPolicy.retryableStatusCode(responseStatus)) {
if (LOG.isDebugEnabled()) {
@@ -169,28 +173,6 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
});
}
private Response executeWithLoadBalancerLifecycleProcessing(Request.Options options, Request feignRequest,
ServiceInstance retrievedServiceInstance, boolean loadBalanced,
Set<LoadBalancerLifecycle> supportedLifecycleProcessors) throws IOException {
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
retrievedServiceInstance);
try {
Response response = delegate.execute(feignRequest, options);
if (loadBalanced) {
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, lbResponse, response)));
}
return response;
}
catch (Exception exception) {
if (loadBalanced) {
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbResponse)));
}
throw exception;
}
}
private RetryTemplate buildRetryTemplate(String serviceId, Request request, LoadBalancedRetryPolicy retryPolicy) {
RetryTemplate retryTemplate = new RetryTemplate();
BackOffPolicy backOffPolicy = this.loadBalancedRetryFactory.createBackOffPolicy(serviceId);