com.netflix.client.AbstractLoadBalancerAwareClient Maven / Gradle / Ivy
/*
*
* Copyright 2013 Netflix, Inc.
*
* 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
*
* http://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 com.netflix.client;
import java.net.URI;
import rx.Observable;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.LoadBalancerContext;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.reactive.LoadBalancerCommand;
import com.netflix.loadbalancer.reactive.ServerOperation;
/**
* Abstract class that provides the integration of client with load balancers.
*
* @author awang
*
*/
public abstract class AbstractLoadBalancerAwareClient extends LoadBalancerContext implements IClient, IClientConfigAware {
public AbstractLoadBalancerAwareClient(ILoadBalancer lb) {
super(lb);
}
/**
* Delegate to {@link #initWithNiwsConfig(IClientConfig)}
* @param clientConfig
*/
public AbstractLoadBalancerAwareClient(ILoadBalancer lb, IClientConfig clientConfig) {
super(lb, clientConfig);
}
/**
* Determine if an exception should contribute to circuit breaker trip. If such exceptions happen consecutively
* on a server, it will be deemed as circuit breaker tripped and enter into a time out when it will be
* skipped by the {@link AvailabilityFilteringRule}, which is the default rule for load balancers.
*/
@Deprecated
protected boolean isCircuitBreakerException(Throwable e) {
if (getRetryHandler() != null) {
return getRetryHandler().isCircuitTrippingException(e);
}
return false;
}
/**
* Determine if operation can be retried if an exception is thrown. For example, connect
* timeout related exceptions
* are typically retriable.
*
*/
@Deprecated
protected boolean isRetriableException(Throwable e) {
if (getRetryHandler() != null) {
return getRetryHandler().isRetriableException(e, true);
}
return false;
}
public T executeWithLoadBalancer(S request) throws ClientException {
return executeWithLoadBalancer(request, null);
}
/**
* This method should be used when the caller wants to dispatch the request to a server chosen by
* the load balancer, instead of specifying the server in the request's URI.
* It calculates the final URI by calling {@link #reconstructURIWithServer(com.netflix.loadbalancer.Server, java.net.URI)}
* and then calls {@link #executeWithLoadBalancer(ClientRequest, com.netflix.client.config.IClientConfig)}.
*
* @param request request to be dispatched to a server chosen by the load balancer. The URI can be a partial
* URI which does not contain the host name or the protocol.
*/
public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
LoadBalancerCommand command = buildLoadBalancerCommand(request, requestConfig);
try {
return command.submit(
new ServerOperation() {
@Override
public Observable call(Server server) {
URI finalUri = reconstructURIWithServer(server, request.getUri());
S requestForServer = (S) request.replaceUri(finalUri);
try {
return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
}
catch (Exception e) {
return Observable.error(e);
}
}
})
.toBlocking()
.single();
} catch (Exception e) {
Throwable t = e.getCause();
if (t instanceof ClientException) {
throw (ClientException) t;
} else {
throw new ClientException(e);
}
}
}
public abstract RequestSpecificRetryHandler getRequestSpecificRetryHandler(S request, IClientConfig requestConfig);
protected LoadBalancerCommand buildLoadBalancerCommand(final S request, final IClientConfig config) {
RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, config);
LoadBalancerCommand.Builder builder = LoadBalancerCommand.builder()
.withLoadBalancerContext(this)
.withRetryHandler(handler)
.withLoadBalancerURI(request.getUri());
customizeLoadBalancerCommandBuilder(request, config, builder);
return builder.build();
}
protected void customizeLoadBalancerCommandBuilder(final S request, final IClientConfig config,
final LoadBalancerCommand.Builder builder) {
// do nothing by default, give a chance to its derived class to customize the builder
}
@Deprecated
protected boolean isRetriable(S request) {
if (request.isRetriable()) {
return true;
} else {
boolean retryOkayOnOperation = okToRetryOnAllOperations;
IClientConfig overriddenClientConfig = request.getOverrideConfig();
if (overriddenClientConfig != null) {
retryOkayOnOperation = overriddenClientConfig.get(CommonClientConfigKey.RequestSpecificRetryOn, okToRetryOnAllOperations);
}
return retryOkayOnOperation;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy