• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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.annotations.VisibleForTesting;
20 import io.grpc.ServiceProviders.PriorityAccessor;
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.List;
24 
25 /**
26  * Provider of managed channels for transport agnostic consumption.
27  *
28  * <p>Implementations <em>should not</em> throw. If they do, it may interrupt class loading. If
29  * exceptions may reasonably occur for implementation-specific reasons, implementations should
30  * generally handle the exception gracefully and return {@code false} from {@link #isAvailable()}.
31  */
32 @Internal
33 public abstract class ManagedChannelProvider {
34   @VisibleForTesting
35   static final Iterable<Class<?>> HARDCODED_CLASSES = new HardcodedClasses();
36 
37   private static final ManagedChannelProvider provider = ServiceProviders.load(
38       ManagedChannelProvider.class,
39       HARDCODED_CLASSES,
40       ManagedChannelProvider.class.getClassLoader(),
41       new PriorityAccessor<ManagedChannelProvider>() {
42         @Override
43         public boolean isAvailable(ManagedChannelProvider provider) {
44           return provider.isAvailable();
45         }
46 
47         @Override
48         public int getPriority(ManagedChannelProvider provider) {
49           return provider.priority();
50         }
51       });
52 
53   /**
54    * Returns the ClassLoader-wide default channel.
55    *
56    * @throws ProviderNotFoundException if no provider is available
57    */
provider()58   public static ManagedChannelProvider provider() {
59     if (provider == null) {
60       throw new ProviderNotFoundException("No functional channel service provider found. "
61           + "Try adding a dependency on the grpc-okhttp, grpc-netty, or grpc-netty-shaded "
62           + "artifact");
63     }
64     return provider;
65   }
66 
67   /**
68    * Whether this provider is available for use, taking the current environment into consideration.
69    * If {@code false}, no other methods are safe to be called.
70    */
isAvailable()71   protected abstract boolean isAvailable();
72 
73   /**
74    * A priority, from 0 to 10 that this provider should be used, taking the current environment into
75    * consideration. 5 should be considered the default, and then tweaked based on environment
76    * detection. A priority of 0 does not imply that the provider wouldn't work; just that it should
77    * be last in line.
78    */
priority()79   protected abstract int priority();
80 
81   /**
82    * Creates a new builder with the given host and port.
83    */
builderForAddress(String name, int port)84   protected abstract ManagedChannelBuilder<?> builderForAddress(String name, int port);
85 
86   /**
87    * Creates a new builder with the given target URI.
88    */
builderForTarget(String target)89   protected abstract ManagedChannelBuilder<?> builderForTarget(String target);
90 
91   /**
92    * Thrown when no suitable {@link ManagedChannelProvider} objects can be found.
93    */
94   public static final class ProviderNotFoundException extends RuntimeException {
95     private static final long serialVersionUID = 1;
96 
ProviderNotFoundException(String msg)97     public ProviderNotFoundException(String msg) {
98       super(msg);
99     }
100   }
101 
102   private static final class HardcodedClasses implements Iterable<Class<?>> {
103     @Override
iterator()104     public Iterator<Class<?>> iterator() {
105       List<Class<?>> list = new ArrayList<Class<?>>();
106       try {
107         list.add(Class.forName("io.grpc.okhttp.OkHttpChannelProvider"));
108       } catch (ClassNotFoundException ex) {
109         // ignore
110       }
111       try {
112         list.add(Class.forName("io.grpc.netty.NettyChannelProvider"));
113       } catch (ClassNotFoundException ex) {
114         // ignore
115       }
116       return list.iterator();
117     }
118   }
119 }
120