blob: ea79c4ebf30f48d12e086b8ad29d88ae42317764 [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
Kun Zhang942f4c92015-09-04 17:21:44 -070034import com.google.common.base.Preconditions;
buchgr602473d2015-11-11 12:53:08 +010035import com.google.common.util.concurrent.MoreExecutors;
zhangkun8d6d12e2014-10-15 13:04:19 -070036
Kun Zhang942f4c92015-09-04 17:21:44 -070037import io.grpc.Attributes;
38import io.grpc.ClientInterceptor;
Kun Zhang942f4c92015-09-04 17:21:44 -070039import io.grpc.LoadBalancer;
40import io.grpc.ManagedChannelBuilder;
41import io.grpc.NameResolver;
Kun Zhangefac6792015-10-22 14:59:44 -070042import io.grpc.NameResolverRegistry;
Kun Zhang942f4c92015-09-04 17:21:44 -070043import io.grpc.ResolvedServerInfo;
44import io.grpc.SimpleLoadBalancerFactory;
45
46import java.net.SocketAddress;
47import java.net.URI;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070048import java.util.ArrayList;
49import java.util.Arrays;
Kun Zhang942f4c92015-09-04 17:21:44 -070050import java.util.Collections;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070051import java.util.List;
Louis Ryan6a782a02015-09-03 14:27:48 -070052import java.util.concurrent.Executor;
zhangkun8d6d12e2014-10-15 13:04:19 -070053
54import javax.annotation.Nullable;
55
56/**
57 * The base class for channel builders.
nathanmittler0304b3d2014-10-24 13:39:13 -070058 *
nmittlerb687bdc2015-08-31 16:13:39 -070059 * @param <T> The concrete type of this builder.
zhangkun8d6d12e2014-10-15 13:04:19 -070060 */
nmittlerb687bdc2015-08-31 16:13:39 -070061public abstract class AbstractManagedChannelImplBuilder
62 <T extends AbstractManagedChannelImplBuilder<T>> extends ManagedChannelBuilder<T> {
Eric Andersonaeeebb72014-12-19 16:41:03 -080063
ejona7235a392015-01-13 13:38:54 -080064 @Nullable
Louis Ryan6a782a02015-09-03 14:27:48 -070065 private Executor executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070066 private final List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
zhangkun8d6d12e2014-10-15 13:04:19 -070067
Kun Zhangefac6792015-10-22 14:59:44 -070068 private final String target;
Kun Zhang942f4c92015-09-04 17:21:44 -070069
70 @Nullable
71 private final SocketAddress directServerAddress;
72
nmittler8c1d38a2015-06-01 08:31:00 -070073 @Nullable
74 private String userAgent;
75
Kun Zhang942f4c92015-09-04 17:21:44 -070076 @Nullable
77 private String authorityOverride;
78
79 @Nullable
80 private NameResolver.Factory nameResolverFactory;
81
82 @Nullable
83 private LoadBalancer.Factory loadBalancerFactory;
84
Kun Zhangefac6792015-10-22 14:59:44 -070085 protected AbstractManagedChannelImplBuilder(String target) {
Kun Zhang942f4c92015-09-04 17:21:44 -070086 this.target = Preconditions.checkNotNull(target);
87 this.directServerAddress = null;
88 }
89
90 protected AbstractManagedChannelImplBuilder(SocketAddress directServerAddress, String authority) {
Kun Zhangefac6792015-10-22 14:59:44 -070091 this.target = "directaddress:///" + directServerAddress;
Kun Zhang942f4c92015-09-04 17:21:44 -070092 this.directServerAddress = directServerAddress;
93 this.nameResolverFactory = new DirectAddressNameResolverFactory(directServerAddress, authority);
94 }
95
Eric Anderson6122daf2015-09-03 12:14:30 -070096 @Override
buchgr602473d2015-11-11 12:53:08 +010097 public final T directExecutor() {
98 return executor(MoreExecutors.directExecutor());
99 }
100
101 @Override
Louis Ryan6a782a02015-09-03 14:27:48 -0700102 public final T executor(Executor executor) {
nmittler777e9282015-08-19 10:01:52 -0700103 this.executor = executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700104 return thisT();
105 }
106
Eric Anderson6122daf2015-09-03 12:14:30 -0700107 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700108 public final T intercept(List<ClientInterceptor> interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700109 this.interceptors.addAll(interceptors);
110 return thisT();
111 }
112
Eric Anderson6122daf2015-09-03 12:14:30 -0700113 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700114 public final T intercept(ClientInterceptor... interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700115 return intercept(Arrays.asList(interceptors));
116 }
117
Kun Zhang942f4c92015-09-04 17:21:44 -0700118 @Override
119 public final T nameResolverFactory(NameResolver.Factory resolverFactory) {
120 Preconditions.checkState(directServerAddress == null,
121 "directServerAddress is set (%s), which forbids the use of NameResolverFactory",
122 directServerAddress);
123 this.nameResolverFactory = resolverFactory;
124 return thisT();
125 }
126
127 @Override
128 public final T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory) {
129 Preconditions.checkState(directServerAddress == null,
130 "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory",
131 directServerAddress);
132 this.loadBalancerFactory = loadBalancerFactory;
133 return thisT();
134 }
135
nmittlerb687bdc2015-08-31 16:13:39 -0700136 private T thisT() {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700137 @SuppressWarnings("unchecked")
nmittlerb687bdc2015-08-31 16:13:39 -0700138 T thisT = (T) this;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700139 return thisT;
ejona7235a392015-01-13 13:38:54 -0800140 }
141
Eric Anderson6122daf2015-09-03 12:14:30 -0700142 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700143 public final T userAgent(String userAgent) {
nmittler8c1d38a2015-06-01 08:31:00 -0700144 this.userAgent = userAgent;
nmittlerb687bdc2015-08-31 16:13:39 -0700145 return thisT();
nmittler8c1d38a2015-06-01 08:31:00 -0700146 }
147
Eric Anderson6122daf2015-09-03 12:14:30 -0700148 @Override
Kun Zhang942f4c92015-09-04 17:21:44 -0700149 public final T overrideAuthority(String authority) {
150 this.authorityOverride = checkAuthority(authority);
151 return thisT();
152 }
153
154 /**
155 * Verifies the authority is valid. This method exists as an escape hatch for putting in an
156 * authority that is valid, but would fail the default validation provided by this
157 * implementation.
158 */
159 protected String checkAuthority(String authority) {
160 return GrpcUtil.checkAuthority(authority);
161 }
162
163 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700164 public ManagedChannelImpl build() {
Kun Zhang942f4c92015-09-04 17:21:44 -0700165 ClientTransportFactory transportFactory = new AuthorityOverridingTransportFactory(
166 buildTransportFactory(), authorityOverride);
167 return new ManagedChannelImpl(
168 target,
169 // TODO(carl-mastrangelo): Allow clients to pass this in
170 new ExponentialBackoffPolicy.Provider(),
Kun Zhangefac6792015-10-22 14:59:44 -0700171 nameResolverFactory == null ? NameResolverRegistry.getDefaultRegistry()
172 : nameResolverFactory,
Kun Zhangedd57c92015-10-27 12:47:29 -0700173 getNameResolverParams(),
Kun Zhangefac6792015-10-22 14:59:44 -0700174 loadBalancerFactory == null ? SimpleLoadBalancerFactory.getInstance()
175 : loadBalancerFactory,
Kun Zhang942f4c92015-09-04 17:21:44 -0700176 transportFactory, executor, userAgent, interceptors);
zhangkun8d6d12e2014-10-15 13:04:19 -0700177 }
178
179 /**
Kun Zhangedd57c92015-10-27 12:47:29 -0700180 * Subclasses should override this method to provide the {@link ClientTransportFactory}
181 * appropriate for this channel. This method is meant for Transport implementors and should not
182 * be used by normal users.
zhangkun8d6d12e2014-10-15 13:04:19 -0700183 */
nmittler777e9282015-08-19 10:01:52 -0700184 protected abstract ClientTransportFactory buildTransportFactory();
Kun Zhang942f4c92015-09-04 17:21:44 -0700185
Kun Zhangedd57c92015-10-27 12:47:29 -0700186 /**
187 * Subclasses can override this method to provide additional parameters to {@link
188 * NameResolver.Factory#newNameResolver}. The default implementation returns {@link
189 * Attributes.EMPTY}.
190 */
191 protected Attributes getNameResolverParams() {
192 return Attributes.EMPTY;
193 }
194
Kun Zhang942f4c92015-09-04 17:21:44 -0700195 private static class AuthorityOverridingTransportFactory implements ClientTransportFactory {
196 final ClientTransportFactory factory;
197 @Nullable final String authorityOverride;
198
199 AuthorityOverridingTransportFactory(
200 ClientTransportFactory factory, @Nullable String authorityOverride) {
201 this.factory = factory;
202 this.authorityOverride = authorityOverride;
203 }
204
205 @Override
206 public ClientTransport newClientTransport(SocketAddress serverAddress, String authority) {
207 return factory.newClientTransport(
208 serverAddress, authorityOverride != null ? authorityOverride : authority);
209 }
210
211 @Override
212 public int referenceCount() {
213 return factory.referenceCount();
214 }
215
216 @Override
217 public ReferenceCounted retain() {
218 factory.retain();
219 return this;
220 }
221
222 @Override
223 public ReferenceCounted release() {
224 factory.release();
225 return this;
226 }
227 }
228
229 private static class DirectAddressNameResolverFactory extends NameResolver.Factory {
230 final SocketAddress address;
231 final String authority;
232
233 DirectAddressNameResolverFactory(SocketAddress address, String authority) {
234 this.address = address;
235 this.authority = authority;
236 }
237
238 @Override
Kun Zhangedd57c92015-10-27 12:47:29 -0700239 public NameResolver newNameResolver(URI notUsedUri, Attributes params) {
Kun Zhang942f4c92015-09-04 17:21:44 -0700240 return new NameResolver() {
241 @Override
242 public String getServiceAuthority() {
243 return authority;
244 }
245
246 @Override
247 public void start(final Listener listener) {
248 listener.onUpdate(
249 Collections.singletonList(new ResolvedServerInfo(address, Attributes.EMPTY)),
250 Attributes.EMPTY);
251 }
252
253 @Override
254 public void shutdown() {}
255 };
256 }
257 }
zhangkun8d6d12e2014-10-15 13:04:19 -0700258}