blob: 93723ea46da9dbc72f26ab5de95c432561dd119c [file] [log] [blame]
Carl Mastrangelo416b7452015-09-09 15:56:47 -07001/*
2 * Copyright 2015, Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32package io.grpc;
33
34import com.google.common.annotations.VisibleForTesting;
35
36import io.grpc.ManagedChannelProvider.ProviderNotFoundException;
37
38import java.util.ServiceLoader;
39
40/**
41 * Provider of servers for transport agnostic consumption.
42 *
43 * <p>Implementations <em>should not</em> throw. If they do, it may interrupt class loading. If
44 * exceptions may reasonably occur for implementation-specific reasons, implementations should
45 * generally handle the exception gracefully and return {@code false} from {@link #isAvailable()}.
46 */
47@Internal
48public abstract class ServerProvider {
49 private static final ServerProvider provider =
50 load(Thread.currentThread().getContextClassLoader());
51
52 @VisibleForTesting
53 static final ServerProvider load(ClassLoader cl) {
54 ServiceLoader<ServerProvider> providers = ServiceLoader.load(ServerProvider.class, cl);
55 ServerProvider best = null;
56
57 for (ServerProvider current : providers) {
58 if (!current.isAvailable()) {
59 continue;
60 } else if (best == null) {
61 best = current;
62 } else if (current.priority() > best.priority()) {
63 best = current;
64 }
65 }
66 return best;
67 }
68
69 /**
70 * Returns the ClassLoader-wide default server.
71 *
72 * @throws ProviderNotFoundException if no provider is available
73 */
74 public static ServerProvider provider() {
75 if (provider == null) {
76 throw new ProviderNotFoundException("No functional server found. "
77 + "Try adding a dependency on the grpc-netty artifact");
78 }
79 return provider;
80 }
81
82 /**
83 * Whether this provider is available for use, taking the current environment into consideration.
84 * If {@code false}, no other methods are safe to be called.
85 */
86 protected abstract boolean isAvailable();
87
88 /**
89 * A priority, from 0 to 10 that this provider should be used, taking the current environment into
90 * consideration. 5 should be considered the default, and then tweaked based on environment
91 * detection. A priority of 0 does not imply that the provider wouldn't work; just that it should
92 * be last in line.
93 */
94 protected abstract int priority();
95
96 /**
97 * Creates a new builder with the given port.
98 */
99 protected abstract ServerBuilder<?> builderForPort(int port);
100}
101