blob: d14b09f1c7e95e7db6c3ce36a7f6352cb1ecea60 [file] [log] [blame]
lryan56e307f2014-12-05 13:25:08 -08001/*
2 * Copyright 2014, 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
nmittlerb687bdc2015-08-31 16:13:39 -070032package io.grpc.internal;
zhangkun8d6d12e2014-10-15 13:04:19 -070033
Carl Mastrangelo82a79d82015-12-07 14:40:11 -080034import static com.google.common.base.MoreObjects.firstNonNull;
35
Kun Zhang942f4c92015-09-04 17:21:44 -070036import com.google.common.base.Preconditions;
buchgr602473d2015-11-11 12:53:08 +010037import com.google.common.util.concurrent.MoreExecutors;
zhangkun8d6d12e2014-10-15 13:04:19 -070038
Kun Zhang942f4c92015-09-04 17:21:44 -070039import io.grpc.Attributes;
40import io.grpc.ClientInterceptor;
Carl Mastrangelo82a79d82015-12-07 14:40:11 -080041import io.grpc.CompressorRegistry;
42import io.grpc.DecompressorRegistry;
Kun Zhang942f4c92015-09-04 17:21:44 -070043import io.grpc.LoadBalancer;
44import io.grpc.ManagedChannelBuilder;
45import io.grpc.NameResolver;
Kun Zhangefac6792015-10-22 14:59:44 -070046import io.grpc.NameResolverRegistry;
Kun Zhang942f4c92015-09-04 17:21:44 -070047import io.grpc.ResolvedServerInfo;
48import io.grpc.SimpleLoadBalancerFactory;
49
50import java.net.SocketAddress;
51import java.net.URI;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070052import java.util.ArrayList;
53import java.util.Arrays;
Kun Zhang942f4c92015-09-04 17:21:44 -070054import java.util.Collections;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070055import java.util.List;
Louis Ryan6a782a02015-09-03 14:27:48 -070056import java.util.concurrent.Executor;
zhangkun8d6d12e2014-10-15 13:04:19 -070057
58import javax.annotation.Nullable;
59
60/**
61 * The base class for channel builders.
nathanmittler0304b3d2014-10-24 13:39:13 -070062 *
nmittlerb687bdc2015-08-31 16:13:39 -070063 * @param <T> The concrete type of this builder.
zhangkun8d6d12e2014-10-15 13:04:19 -070064 */
nmittlerb687bdc2015-08-31 16:13:39 -070065public abstract class AbstractManagedChannelImplBuilder
66 <T extends AbstractManagedChannelImplBuilder<T>> extends ManagedChannelBuilder<T> {
Kun Zhang16247152015-12-08 17:52:05 -080067 private static final String DIRECT_ADDRESS_SCHEME = "directaddress";
Eric Andersonaeeebb72014-12-19 16:41:03 -080068
ejona7235a392015-01-13 13:38:54 -080069 @Nullable
Louis Ryan6a782a02015-09-03 14:27:48 -070070 private Executor executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070071 private final List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
zhangkun8d6d12e2014-10-15 13:04:19 -070072
Kun Zhangefac6792015-10-22 14:59:44 -070073 private final String target;
Kun Zhang942f4c92015-09-04 17:21:44 -070074
75 @Nullable
76 private final SocketAddress directServerAddress;
77
nmittler8c1d38a2015-06-01 08:31:00 -070078 @Nullable
79 private String userAgent;
80
Kun Zhang942f4c92015-09-04 17:21:44 -070081 @Nullable
82 private String authorityOverride;
83
84 @Nullable
85 private NameResolver.Factory nameResolverFactory;
86
87 @Nullable
88 private LoadBalancer.Factory loadBalancerFactory;
89
Carl Mastrangelo82a79d82015-12-07 14:40:11 -080090 @Nullable
91 private DecompressorRegistry decompressorRegistry;
92
93 @Nullable
94 private CompressorRegistry compressorRegistry;
95
Kun Zhangefac6792015-10-22 14:59:44 -070096 protected AbstractManagedChannelImplBuilder(String target) {
Kun Zhang942f4c92015-09-04 17:21:44 -070097 this.target = Preconditions.checkNotNull(target);
98 this.directServerAddress = null;
99 }
100
101 protected AbstractManagedChannelImplBuilder(SocketAddress directServerAddress, String authority) {
Kun Zhang16247152015-12-08 17:52:05 -0800102 this.target = DIRECT_ADDRESS_SCHEME + ":///" + directServerAddress;
Kun Zhang942f4c92015-09-04 17:21:44 -0700103 this.directServerAddress = directServerAddress;
104 this.nameResolverFactory = new DirectAddressNameResolverFactory(directServerAddress, authority);
105 }
106
Eric Anderson6122daf2015-09-03 12:14:30 -0700107 @Override
buchgr602473d2015-11-11 12:53:08 +0100108 public final T directExecutor() {
109 return executor(MoreExecutors.directExecutor());
110 }
111
112 @Override
Louis Ryan6a782a02015-09-03 14:27:48 -0700113 public final T executor(Executor executor) {
nmittler777e9282015-08-19 10:01:52 -0700114 this.executor = executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700115 return thisT();
116 }
117
Eric Anderson6122daf2015-09-03 12:14:30 -0700118 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700119 public final T intercept(List<ClientInterceptor> interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700120 this.interceptors.addAll(interceptors);
121 return thisT();
122 }
123
Eric Anderson6122daf2015-09-03 12:14:30 -0700124 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700125 public final T intercept(ClientInterceptor... interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700126 return intercept(Arrays.asList(interceptors));
127 }
128
Kun Zhang942f4c92015-09-04 17:21:44 -0700129 @Override
130 public final T nameResolverFactory(NameResolver.Factory resolverFactory) {
131 Preconditions.checkState(directServerAddress == null,
132 "directServerAddress is set (%s), which forbids the use of NameResolverFactory",
133 directServerAddress);
134 this.nameResolverFactory = resolverFactory;
135 return thisT();
136 }
137
138 @Override
139 public final T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory) {
140 Preconditions.checkState(directServerAddress == null,
141 "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory",
142 directServerAddress);
143 this.loadBalancerFactory = loadBalancerFactory;
144 return thisT();
145 }
146
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800147 @Override
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800148 public final T decompressorRegistry(DecompressorRegistry registry) {
149 this.decompressorRegistry = registry;
150 return thisT();
151 }
152
153 @Override
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800154 public final T compressorRegistry(CompressorRegistry registry) {
155 this.compressorRegistry = registry;
156 return thisT();
157 }
158
nmittlerb687bdc2015-08-31 16:13:39 -0700159 private T thisT() {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700160 @SuppressWarnings("unchecked")
nmittlerb687bdc2015-08-31 16:13:39 -0700161 T thisT = (T) this;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700162 return thisT;
ejona7235a392015-01-13 13:38:54 -0800163 }
164
Eric Anderson6122daf2015-09-03 12:14:30 -0700165 @Override
Carl Mastrangelo1cc76d82016-05-24 16:29:26 -0700166 public final T userAgent(@Nullable String userAgent) {
nmittler8c1d38a2015-06-01 08:31:00 -0700167 this.userAgent = userAgent;
nmittlerb687bdc2015-08-31 16:13:39 -0700168 return thisT();
nmittler8c1d38a2015-06-01 08:31:00 -0700169 }
170
Eric Anderson6122daf2015-09-03 12:14:30 -0700171 @Override
Kun Zhang942f4c92015-09-04 17:21:44 -0700172 public final T overrideAuthority(String authority) {
173 this.authorityOverride = checkAuthority(authority);
174 return thisT();
175 }
176
177 /**
178 * Verifies the authority is valid. This method exists as an escape hatch for putting in an
179 * authority that is valid, but would fail the default validation provided by this
180 * implementation.
181 */
182 protected String checkAuthority(String authority) {
183 return GrpcUtil.checkAuthority(authority);
184 }
185
186 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700187 public ManagedChannelImpl build() {
Sky Ao1d8aefa2016-04-18 23:43:30 +0800188 ClientTransportFactory transportFactory = buildTransportFactory();
189 if (authorityOverride != null) {
190 transportFactory = new AuthorityOverridingTransportFactory(
191 transportFactory, authorityOverride);
192 }
Kun Zhang942f4c92015-09-04 17:21:44 -0700193 return new ManagedChannelImpl(
194 target,
Eric Andersona40b6862016-03-25 10:23:58 -0700195 // TODO(carl-mastrangelo): Allow clients to pass this in
196 new ExponentialBackoffPolicy.Provider(),
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800197 firstNonNull(nameResolverFactory, NameResolverRegistry.getDefaultRegistry()),
Kun Zhangedd57c92015-10-27 12:47:29 -0700198 getNameResolverParams(),
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800199 firstNonNull(loadBalancerFactory, SimpleLoadBalancerFactory.getInstance()),
200 transportFactory,
201 firstNonNull(decompressorRegistry, DecompressorRegistry.getDefaultInstance()),
202 firstNonNull(compressorRegistry, CompressorRegistry.getDefaultInstance()),
203 executor, userAgent, interceptors);
zhangkun8d6d12e2014-10-15 13:04:19 -0700204 }
205
206 /**
Kun Zhangedd57c92015-10-27 12:47:29 -0700207 * Subclasses should override this method to provide the {@link ClientTransportFactory}
208 * appropriate for this channel. This method is meant for Transport implementors and should not
209 * be used by normal users.
zhangkun8d6d12e2014-10-15 13:04:19 -0700210 */
nmittler777e9282015-08-19 10:01:52 -0700211 protected abstract ClientTransportFactory buildTransportFactory();
Kun Zhang942f4c92015-09-04 17:21:44 -0700212
Kun Zhangedd57c92015-10-27 12:47:29 -0700213 /**
214 * Subclasses can override this method to provide additional parameters to {@link
215 * NameResolver.Factory#newNameResolver}. The default implementation returns {@link
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800216 * Attributes#EMPTY}.
Kun Zhangedd57c92015-10-27 12:47:29 -0700217 */
218 protected Attributes getNameResolverParams() {
219 return Attributes.EMPTY;
220 }
221
Kun Zhang942f4c92015-09-04 17:21:44 -0700222 private static class AuthorityOverridingTransportFactory implements ClientTransportFactory {
223 final ClientTransportFactory factory;
Sky Ao1d8aefa2016-04-18 23:43:30 +0800224 final String authorityOverride;
Kun Zhang942f4c92015-09-04 17:21:44 -0700225
226 AuthorityOverridingTransportFactory(
Sky Ao1d8aefa2016-04-18 23:43:30 +0800227 ClientTransportFactory factory, String authorityOverride) {
228 this.factory = Preconditions.checkNotNull(factory, "factory should not be null");
229 this.authorityOverride = Preconditions.checkNotNull(
230 authorityOverride, "authorityOverride should not be null");
Kun Zhang942f4c92015-09-04 17:21:44 -0700231 }
232
233 @Override
Kun Zhangcf787bd2016-01-29 17:25:42 -0800234 public ManagedClientTransport newClientTransport(SocketAddress serverAddress,
Carl Mastrangelo1cc76d82016-05-24 16:29:26 -0700235 String authority, @Nullable String userAgent) {
236 return factory.newClientTransport(serverAddress, authorityOverride, userAgent);
Kun Zhang942f4c92015-09-04 17:21:44 -0700237 }
238
239 @Override
buchgr3c68c052016-03-17 00:14:43 +0100240 public void close() {
241 factory.close();
Kun Zhang942f4c92015-09-04 17:21:44 -0700242 }
243 }
244
245 private static class DirectAddressNameResolverFactory extends NameResolver.Factory {
246 final SocketAddress address;
247 final String authority;
248
249 DirectAddressNameResolverFactory(SocketAddress address, String authority) {
250 this.address = address;
251 this.authority = authority;
252 }
253
254 @Override
Kun Zhangedd57c92015-10-27 12:47:29 -0700255 public NameResolver newNameResolver(URI notUsedUri, Attributes params) {
Kun Zhang942f4c92015-09-04 17:21:44 -0700256 return new NameResolver() {
257 @Override
258 public String getServiceAuthority() {
259 return authority;
260 }
261
262 @Override
263 public void start(final Listener listener) {
264 listener.onUpdate(
265 Collections.singletonList(new ResolvedServerInfo(address, Attributes.EMPTY)),
266 Attributes.EMPTY);
267 }
268
269 @Override
270 public void shutdown() {}
271 };
272 }
Kun Zhang16247152015-12-08 17:52:05 -0800273
274 @Override
275 public String getDefaultScheme() {
276 return DIRECT_ADDRESS_SCHEME;
277 }
Kun Zhang942f4c92015-09-04 17:21:44 -0700278 }
zhangkun8d6d12e2014-10-15 13:04:19 -0700279}