1 /* 2 * Copyright 2018 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc; 18 19 import com.google.common.base.MoreObjects; 20 import io.grpc.NameResolver.ConfigOrError; 21 import java.util.Map; 22 23 /** 24 * Provider of {@link LoadBalancer}s. Each provider is bounded to a load-balancing policy name. 25 * 26 * <p>Implementations can be automatically discovered by gRPC via Java's SPI mechanism. For 27 * automatic discovery, the implementation must have a zero-argument constructor and include 28 * a resource named {@code META-INF/services/io.grpc.LoadBalancerProvider} in their JAR. The 29 * file's contents should be the implementation's class name. Implementations that need arguments in 30 * their constructor can be manually registered by {@link LoadBalancerRegistry#register}. 31 * 32 * <p>Implementations <em>should not</em> throw. If they do, it may interrupt class loading. If 33 * exceptions may reasonably occur for implementation-specific reasons, implementations should 34 * generally handle the exception gracefully and return {@code false} from {@link #isAvailable()}. 35 * 36 * @since 1.17.0 37 */ 38 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771") 39 public abstract class LoadBalancerProvider extends LoadBalancer.Factory { 40 41 /** 42 * A sentinel value indicating that service config is not supported. This can be used to 43 * indicate that parsing of the service config is neither right nor wrong, but doesn't have 44 * any meaning. 45 */ 46 private static final ConfigOrError UNKNOWN_CONFIG = ConfigOrError.fromConfig(new UnknownConfig()); 47 48 /** 49 * Whether this provider is available for use, taking the current environment into consideration. 50 * If {@code false}, {@link #newLoadBalancer} is not safe to be called. 51 */ isAvailable()52 public abstract boolean isAvailable(); 53 54 /** 55 * A priority, from 0 to 10 that this provider should be used, taking the current environment into 56 * consideration. 5 should be considered the default, and then tweaked based on environment 57 * detection. A priority of 0 does not imply that the provider wouldn't work; just that it should 58 * be last in line. 59 */ getPriority()60 public abstract int getPriority(); 61 62 /** 63 * Returns the load-balancing policy name associated with this provider, which makes it selectable 64 * via {@link LoadBalancerRegistry#getProvider}. This is called only when the class is loaded. It 65 * shouldn't change, and there is no point doing so. 66 * 67 * <p>The policy name should consist of only lower case letters letters, underscore and digits, 68 * and can only start with letters. 69 */ getPolicyName()70 public abstract String getPolicyName(); 71 72 /** 73 * Parses the config for the Load Balancing policy unpacked from the service config. This will 74 * return a {@link ConfigOrError} which contains either the successfully parsed config, or the 75 * {@link Status} representing the failure to parse. Implementations are expected to not throw 76 * exceptions but return a Status representing the failure. If successful, the load balancing 77 * policy config should be immutable. 78 * 79 * @param rawLoadBalancingPolicyConfig The {@link Map} representation of the load balancing 80 * policy choice. 81 * @return a tuple of the fully parsed and validated balancer configuration, else the Status. 82 * @since 1.20.0 83 * @see <a href="https://github.com/grpc/proposal/blob/master/A24-lb-policy-config.md"> 84 * A24-lb-policy-config.md</a> 85 */ parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig)86 public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig) { 87 return UNKNOWN_CONFIG; 88 } 89 90 @Override toString()91 public final String toString() { 92 return MoreObjects.toStringHelper(this) 93 .add("policy", getPolicyName()) 94 .add("priority", getPriority()) 95 .add("available", isAvailable()) 96 .toString(); 97 } 98 99 /** 100 * Uses identity equality. 101 */ 102 @Override equals(Object other)103 public final boolean equals(Object other) { 104 return this == other; 105 } 106 107 @Override hashCode()108 public final int hashCode() { 109 return super.hashCode(); 110 } 111 112 private static final class UnknownConfig { 113 UnknownConfig()114 UnknownConfig() {} 115 116 @Override toString()117 public String toString() { 118 return "service config is unused"; 119 } 120 } 121 } 122