• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.grpclb;
18 
19 import com.google.common.base.Stopwatch;
20 import io.grpc.Context;
21 import io.grpc.Internal;
22 import io.grpc.LoadBalancer;
23 import io.grpc.LoadBalancerProvider;
24 import io.grpc.NameResolver.ConfigOrError;
25 import io.grpc.Status;
26 import io.grpc.grpclb.GrpclbState.Mode;
27 import io.grpc.internal.ExponentialBackoffPolicy;
28 import io.grpc.internal.JsonUtil;
29 import io.grpc.internal.ServiceConfigUtil;
30 import io.grpc.internal.ServiceConfigUtil.LbConfig;
31 import io.grpc.internal.TimeProvider;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.Map;
35 
36 /**
37  * The provider for the "grpclb" balancing policy.  This class should not be directly referenced in
38  * code.  The policy should be accessed through {@link io.grpc.LoadBalancerRegistry#getProvider}
39  * with the name "grpclb".
40  */
41 @Internal
42 public final class GrpclbLoadBalancerProvider extends LoadBalancerProvider {
43 
44   private static final Mode DEFAULT_MODE = Mode.ROUND_ROBIN;
45 
46   @Override
isAvailable()47   public boolean isAvailable() {
48     return true;
49   }
50 
51   @Override
getPriority()52   public int getPriority() {
53     return 5;
54   }
55 
56   @Override
getPolicyName()57   public String getPolicyName() {
58     return "grpclb";
59   }
60 
61   @Override
newLoadBalancer(LoadBalancer.Helper helper)62   public LoadBalancer newLoadBalancer(LoadBalancer.Helper helper) {
63     return
64         new GrpclbLoadBalancer(
65             helper,
66             Context.ROOT,
67             new CachedSubchannelPool(helper),
68             TimeProvider.SYSTEM_TIME_PROVIDER,
69             Stopwatch.createUnstarted(),
70             new ExponentialBackoffPolicy.Provider());
71   }
72 
73   @Override
parseLoadBalancingPolicyConfig( Map<String, ?> rawLoadBalancingConfigPolicy)74   public ConfigOrError parseLoadBalancingPolicyConfig(
75       Map<String, ?> rawLoadBalancingConfigPolicy) {
76     try {
77       return parseLoadBalancingConfigPolicyInternal(rawLoadBalancingConfigPolicy);
78     } catch (RuntimeException e) {
79       return ConfigOrError.fromError(
80           Status.fromThrowable(e).withDescription(
81               "Failed to parse GRPCLB config: " + rawLoadBalancingConfigPolicy));
82     }
83   }
84 
parseLoadBalancingConfigPolicyInternal( Map<String, ?> rawLoadBalancingPolicyConfig)85   ConfigOrError parseLoadBalancingConfigPolicyInternal(
86       Map<String, ?> rawLoadBalancingPolicyConfig) {
87     if (rawLoadBalancingPolicyConfig == null) {
88       return ConfigOrError.fromConfig(GrpclbConfig.create(DEFAULT_MODE));
89     }
90     String serviceName = JsonUtil.getString(rawLoadBalancingPolicyConfig, "serviceName");
91     List<?> rawChildPolicies = JsonUtil.getList(rawLoadBalancingPolicyConfig, "childPolicy");
92     Long initialFallbackTimeoutNs =
93         JsonUtil.getStringAsDuration(rawLoadBalancingPolicyConfig, "initialFallbackTimeout");
94     long timeoutMs = GrpclbState.FALLBACK_TIMEOUT_MS;
95     if (initialFallbackTimeoutNs != null) {
96       timeoutMs = initialFallbackTimeoutNs / 1000000;
97     }
98 
99     List<LbConfig> childPolicies = null;
100     if (rawChildPolicies != null) {
101       childPolicies =
102           ServiceConfigUtil
103               .unwrapLoadBalancingConfigList(JsonUtil.checkObjectList(rawChildPolicies));
104     }
105 
106     if (childPolicies == null || childPolicies.isEmpty()) {
107       return ConfigOrError.fromConfig(
108           GrpclbConfig.create(DEFAULT_MODE, serviceName, timeoutMs));
109     }
110 
111     List<String> policiesTried = new ArrayList<>();
112     for (LbConfig childPolicy : childPolicies) {
113       String childPolicyName = childPolicy.getPolicyName();
114       switch (childPolicyName) {
115         case "round_robin":
116           return ConfigOrError.fromConfig(
117               GrpclbConfig.create(Mode.ROUND_ROBIN, serviceName, timeoutMs));
118         case "pick_first":
119           return ConfigOrError.fromConfig(
120               GrpclbConfig.create(Mode.PICK_FIRST, serviceName, timeoutMs));
121         default:
122           policiesTried.add(childPolicyName);
123       }
124     }
125     return ConfigOrError.fromError(
126         Status
127             .UNAVAILABLE
128             .withDescription(
129                 "None of " + policiesTried + " specified child policies are available."));
130   }
131 }
132