blob: 4cb74e9b9851bc9da23ece5d19b0206f02659cb4 [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 Zhang631a9d52016-06-02 16:47:36 -070036import com.google.common.annotations.VisibleForTesting;
Kun Zhang942f4c92015-09-04 17:21:44 -070037import com.google.common.base.Preconditions;
buchgr602473d2015-11-11 12:53:08 +010038import com.google.common.util.concurrent.MoreExecutors;
zhangkun8d6d12e2014-10-15 13:04:19 -070039
Kun Zhang942f4c92015-09-04 17:21:44 -070040import io.grpc.Attributes;
41import io.grpc.ClientInterceptor;
Carl Mastrangelo82a79d82015-12-07 14:40:11 -080042import io.grpc.CompressorRegistry;
43import io.grpc.DecompressorRegistry;
Kun Zhang942f4c92015-09-04 17:21:44 -070044import io.grpc.LoadBalancer;
45import io.grpc.ManagedChannelBuilder;
46import io.grpc.NameResolver;
Kun Zhangefac6792015-10-22 14:59:44 -070047import io.grpc.NameResolverRegistry;
Kun Zhang942f4c92015-09-04 17:21:44 -070048import io.grpc.ResolvedServerInfo;
49import io.grpc.SimpleLoadBalancerFactory;
50
51import java.net.SocketAddress;
52import java.net.URI;
Kun Zhang631a9d52016-06-02 16:47:36 -070053import java.net.URISyntaxException;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070054import java.util.ArrayList;
55import java.util.Arrays;
Kun Zhang942f4c92015-09-04 17:21:44 -070056import java.util.Collections;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070057import java.util.List;
Louis Ryan6a782a02015-09-03 14:27:48 -070058import java.util.concurrent.Executor;
zhangkun8d6d12e2014-10-15 13:04:19 -070059
60import javax.annotation.Nullable;
61
62/**
63 * The base class for channel builders.
nathanmittler0304b3d2014-10-24 13:39:13 -070064 *
nmittlerb687bdc2015-08-31 16:13:39 -070065 * @param <T> The concrete type of this builder.
zhangkun8d6d12e2014-10-15 13:04:19 -070066 */
nmittlerb687bdc2015-08-31 16:13:39 -070067public abstract class AbstractManagedChannelImplBuilder
68 <T extends AbstractManagedChannelImplBuilder<T>> extends ManagedChannelBuilder<T> {
Kun Zhang16247152015-12-08 17:52:05 -080069 private static final String DIRECT_ADDRESS_SCHEME = "directaddress";
Eric Andersonaeeebb72014-12-19 16:41:03 -080070
ejona7235a392015-01-13 13:38:54 -080071 @Nullable
Louis Ryan6a782a02015-09-03 14:27:48 -070072 private Executor executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070073 private final List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
zhangkun8d6d12e2014-10-15 13:04:19 -070074
Kun Zhangefac6792015-10-22 14:59:44 -070075 private final String target;
Kun Zhang942f4c92015-09-04 17:21:44 -070076
77 @Nullable
78 private final SocketAddress directServerAddress;
79
nmittler8c1d38a2015-06-01 08:31:00 -070080 @Nullable
81 private String userAgent;
82
Kun Zhang942f4c92015-09-04 17:21:44 -070083 @Nullable
84 private String authorityOverride;
85
86 @Nullable
87 private NameResolver.Factory nameResolverFactory;
88
89 @Nullable
90 private LoadBalancer.Factory loadBalancerFactory;
91
Carl Mastrangelo82a79d82015-12-07 14:40:11 -080092 @Nullable
93 private DecompressorRegistry decompressorRegistry;
94
95 @Nullable
96 private CompressorRegistry compressorRegistry;
97
Kun Zhangefac6792015-10-22 14:59:44 -070098 protected AbstractManagedChannelImplBuilder(String target) {
Kun Zhang942f4c92015-09-04 17:21:44 -070099 this.target = Preconditions.checkNotNull(target);
100 this.directServerAddress = null;
101 }
102
Kun Zhang631a9d52016-06-02 16:47:36 -0700103 /**
104 * Returns a target string for the SocketAddress. It is only used as a placeholder, because
105 * DirectAddressNameResolverFactory will not actually try to use it. However, it must be a valid
106 * URI.
107 */
108 @VisibleForTesting
109 static String makeTargetStringForDirectAddress(SocketAddress address) {
110 try {
111 return new URI(DIRECT_ADDRESS_SCHEME, "", "/" + address, null).toString();
112 } catch (URISyntaxException e) {
113 // It should not happen.
114 throw new RuntimeException(e);
115 }
116 }
117
Kun Zhang942f4c92015-09-04 17:21:44 -0700118 protected AbstractManagedChannelImplBuilder(SocketAddress directServerAddress, String authority) {
Kun Zhang631a9d52016-06-02 16:47:36 -0700119 this.target = makeTargetStringForDirectAddress(directServerAddress);
Kun Zhang942f4c92015-09-04 17:21:44 -0700120 this.directServerAddress = directServerAddress;
121 this.nameResolverFactory = new DirectAddressNameResolverFactory(directServerAddress, authority);
122 }
123
Eric Anderson6122daf2015-09-03 12:14:30 -0700124 @Override
buchgr602473d2015-11-11 12:53:08 +0100125 public final T directExecutor() {
126 return executor(MoreExecutors.directExecutor());
127 }
128
129 @Override
Louis Ryan6a782a02015-09-03 14:27:48 -0700130 public final T executor(Executor executor) {
nmittler777e9282015-08-19 10:01:52 -0700131 this.executor = executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700132 return thisT();
133 }
134
Eric Anderson6122daf2015-09-03 12:14:30 -0700135 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700136 public final T intercept(List<ClientInterceptor> interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700137 this.interceptors.addAll(interceptors);
138 return thisT();
139 }
140
Eric Anderson6122daf2015-09-03 12:14:30 -0700141 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700142 public final T intercept(ClientInterceptor... interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700143 return intercept(Arrays.asList(interceptors));
144 }
145
Kun Zhang942f4c92015-09-04 17:21:44 -0700146 @Override
147 public final T nameResolverFactory(NameResolver.Factory resolverFactory) {
148 Preconditions.checkState(directServerAddress == null,
149 "directServerAddress is set (%s), which forbids the use of NameResolverFactory",
150 directServerAddress);
151 this.nameResolverFactory = resolverFactory;
152 return thisT();
153 }
154
155 @Override
156 public final T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory) {
157 Preconditions.checkState(directServerAddress == null,
158 "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory",
159 directServerAddress);
160 this.loadBalancerFactory = loadBalancerFactory;
161 return thisT();
162 }
163
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800164 @Override
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800165 public final T decompressorRegistry(DecompressorRegistry registry) {
166 this.decompressorRegistry = registry;
167 return thisT();
168 }
169
170 @Override
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800171 public final T compressorRegistry(CompressorRegistry registry) {
172 this.compressorRegistry = registry;
173 return thisT();
174 }
175
nmittlerb687bdc2015-08-31 16:13:39 -0700176 private T thisT() {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700177 @SuppressWarnings("unchecked")
nmittlerb687bdc2015-08-31 16:13:39 -0700178 T thisT = (T) this;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700179 return thisT;
ejona7235a392015-01-13 13:38:54 -0800180 }
181
Eric Anderson6122daf2015-09-03 12:14:30 -0700182 @Override
Carl Mastrangelo1cc76d82016-05-24 16:29:26 -0700183 public final T userAgent(@Nullable String userAgent) {
nmittler8c1d38a2015-06-01 08:31:00 -0700184 this.userAgent = userAgent;
nmittlerb687bdc2015-08-31 16:13:39 -0700185 return thisT();
nmittler8c1d38a2015-06-01 08:31:00 -0700186 }
187
Eric Anderson6122daf2015-09-03 12:14:30 -0700188 @Override
Kun Zhang942f4c92015-09-04 17:21:44 -0700189 public final T overrideAuthority(String authority) {
190 this.authorityOverride = checkAuthority(authority);
191 return thisT();
192 }
193
194 /**
195 * Verifies the authority is valid. This method exists as an escape hatch for putting in an
196 * authority that is valid, but would fail the default validation provided by this
197 * implementation.
198 */
199 protected String checkAuthority(String authority) {
200 return GrpcUtil.checkAuthority(authority);
201 }
202
203 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700204 public ManagedChannelImpl build() {
Sky Ao1d8aefa2016-04-18 23:43:30 +0800205 ClientTransportFactory transportFactory = buildTransportFactory();
206 if (authorityOverride != null) {
207 transportFactory = new AuthorityOverridingTransportFactory(
208 transportFactory, authorityOverride);
209 }
Kun Zhang942f4c92015-09-04 17:21:44 -0700210 return new ManagedChannelImpl(
211 target,
Eric Andersona40b6862016-03-25 10:23:58 -0700212 // TODO(carl-mastrangelo): Allow clients to pass this in
213 new ExponentialBackoffPolicy.Provider(),
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800214 firstNonNull(nameResolverFactory, NameResolverRegistry.getDefaultRegistry()),
Kun Zhangedd57c92015-10-27 12:47:29 -0700215 getNameResolverParams(),
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800216 firstNonNull(loadBalancerFactory, SimpleLoadBalancerFactory.getInstance()),
217 transportFactory,
218 firstNonNull(decompressorRegistry, DecompressorRegistry.getDefaultInstance()),
219 firstNonNull(compressorRegistry, CompressorRegistry.getDefaultInstance()),
220 executor, userAgent, interceptors);
zhangkun8d6d12e2014-10-15 13:04:19 -0700221 }
222
223 /**
Kun Zhangedd57c92015-10-27 12:47:29 -0700224 * Subclasses should override this method to provide the {@link ClientTransportFactory}
225 * appropriate for this channel. This method is meant for Transport implementors and should not
226 * be used by normal users.
zhangkun8d6d12e2014-10-15 13:04:19 -0700227 */
nmittler777e9282015-08-19 10:01:52 -0700228 protected abstract ClientTransportFactory buildTransportFactory();
Kun Zhang942f4c92015-09-04 17:21:44 -0700229
Kun Zhangedd57c92015-10-27 12:47:29 -0700230 /**
231 * Subclasses can override this method to provide additional parameters to {@link
232 * NameResolver.Factory#newNameResolver}. The default implementation returns {@link
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800233 * Attributes#EMPTY}.
Kun Zhangedd57c92015-10-27 12:47:29 -0700234 */
235 protected Attributes getNameResolverParams() {
236 return Attributes.EMPTY;
237 }
238
Kun Zhang942f4c92015-09-04 17:21:44 -0700239 private static class AuthorityOverridingTransportFactory implements ClientTransportFactory {
240 final ClientTransportFactory factory;
Sky Ao1d8aefa2016-04-18 23:43:30 +0800241 final String authorityOverride;
Kun Zhang942f4c92015-09-04 17:21:44 -0700242
243 AuthorityOverridingTransportFactory(
Sky Ao1d8aefa2016-04-18 23:43:30 +0800244 ClientTransportFactory factory, String authorityOverride) {
245 this.factory = Preconditions.checkNotNull(factory, "factory should not be null");
246 this.authorityOverride = Preconditions.checkNotNull(
247 authorityOverride, "authorityOverride should not be null");
Kun Zhang942f4c92015-09-04 17:21:44 -0700248 }
249
250 @Override
Kun Zhangcf787bd2016-01-29 17:25:42 -0800251 public ManagedClientTransport newClientTransport(SocketAddress serverAddress,
Carl Mastrangelo1cc76d82016-05-24 16:29:26 -0700252 String authority, @Nullable String userAgent) {
253 return factory.newClientTransport(serverAddress, authorityOverride, userAgent);
Kun Zhang942f4c92015-09-04 17:21:44 -0700254 }
255
256 @Override
buchgr3c68c052016-03-17 00:14:43 +0100257 public void close() {
258 factory.close();
Kun Zhang942f4c92015-09-04 17:21:44 -0700259 }
260 }
261
262 private static class DirectAddressNameResolverFactory extends NameResolver.Factory {
263 final SocketAddress address;
264 final String authority;
265
266 DirectAddressNameResolverFactory(SocketAddress address, String authority) {
267 this.address = address;
268 this.authority = authority;
269 }
270
271 @Override
Kun Zhangedd57c92015-10-27 12:47:29 -0700272 public NameResolver newNameResolver(URI notUsedUri, Attributes params) {
Kun Zhang942f4c92015-09-04 17:21:44 -0700273 return new NameResolver() {
274 @Override
275 public String getServiceAuthority() {
276 return authority;
277 }
278
279 @Override
280 public void start(final Listener listener) {
281 listener.onUpdate(
282 Collections.singletonList(new ResolvedServerInfo(address, Attributes.EMPTY)),
283 Attributes.EMPTY);
284 }
285
286 @Override
287 public void shutdown() {}
288 };
289 }
Kun Zhang16247152015-12-08 17:52:05 -0800290
291 @Override
292 public String getDefaultScheme() {
293 return DIRECT_ADDRESS_SCHEME;
294 }
Kun Zhang942f4c92015-09-04 17:21:44 -0700295 }
zhangkun8d6d12e2014-10-15 13:04:19 -0700296}