blob: 203d0cc5ccd7b624adf94349076e64a6b0cbf76e [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;
zhangkun8d6d12e2014-10-15 13:04:19 -070035
Kun Zhang942f4c92015-09-04 17:21:44 -070036import io.grpc.Attributes;
37import io.grpc.ClientInterceptor;
Kun Zhang942f4c92015-09-04 17:21:44 -070038import io.grpc.LoadBalancer;
39import io.grpc.ManagedChannelBuilder;
40import io.grpc.NameResolver;
Kun Zhangefac6792015-10-22 14:59:44 -070041import io.grpc.NameResolverRegistry;
Kun Zhang942f4c92015-09-04 17:21:44 -070042import io.grpc.ResolvedServerInfo;
43import io.grpc.SimpleLoadBalancerFactory;
44
45import java.net.SocketAddress;
46import java.net.URI;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070047import java.util.ArrayList;
48import java.util.Arrays;
Kun Zhang942f4c92015-09-04 17:21:44 -070049import java.util.Collections;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070050import java.util.List;
Louis Ryan6a782a02015-09-03 14:27:48 -070051import java.util.concurrent.Executor;
zhangkun8d6d12e2014-10-15 13:04:19 -070052
53import javax.annotation.Nullable;
54
55/**
56 * The base class for channel builders.
nathanmittler0304b3d2014-10-24 13:39:13 -070057 *
nmittlerb687bdc2015-08-31 16:13:39 -070058 * @param <T> The concrete type of this builder.
zhangkun8d6d12e2014-10-15 13:04:19 -070059 */
nmittlerb687bdc2015-08-31 16:13:39 -070060public abstract class AbstractManagedChannelImplBuilder
61 <T extends AbstractManagedChannelImplBuilder<T>> extends ManagedChannelBuilder<T> {
Eric Andersonaeeebb72014-12-19 16:41:03 -080062
ejona7235a392015-01-13 13:38:54 -080063 @Nullable
Louis Ryan6a782a02015-09-03 14:27:48 -070064 private Executor executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070065 private final List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
zhangkun8d6d12e2014-10-15 13:04:19 -070066
Kun Zhangefac6792015-10-22 14:59:44 -070067 private final String target;
Kun Zhang942f4c92015-09-04 17:21:44 -070068
69 @Nullable
70 private final SocketAddress directServerAddress;
71
nmittler8c1d38a2015-06-01 08:31:00 -070072 @Nullable
73 private String userAgent;
74
Kun Zhang942f4c92015-09-04 17:21:44 -070075 @Nullable
76 private String authorityOverride;
77
78 @Nullable
79 private NameResolver.Factory nameResolverFactory;
80
81 @Nullable
82 private LoadBalancer.Factory loadBalancerFactory;
83
Kun Zhangefac6792015-10-22 14:59:44 -070084 protected AbstractManagedChannelImplBuilder(String target) {
Kun Zhang942f4c92015-09-04 17:21:44 -070085 this.target = Preconditions.checkNotNull(target);
86 this.directServerAddress = null;
87 }
88
89 protected AbstractManagedChannelImplBuilder(SocketAddress directServerAddress, String authority) {
Kun Zhangefac6792015-10-22 14:59:44 -070090 this.target = "directaddress:///" + directServerAddress;
Kun Zhang942f4c92015-09-04 17:21:44 -070091 this.directServerAddress = directServerAddress;
92 this.nameResolverFactory = new DirectAddressNameResolverFactory(directServerAddress, authority);
93 }
94
Eric Anderson6122daf2015-09-03 12:14:30 -070095 @Override
Louis Ryan6a782a02015-09-03 14:27:48 -070096 public final T executor(Executor executor) {
nmittler777e9282015-08-19 10:01:52 -070097 this.executor = executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070098 return thisT();
99 }
100
Eric Anderson6122daf2015-09-03 12:14:30 -0700101 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700102 public final T intercept(List<ClientInterceptor> interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700103 this.interceptors.addAll(interceptors);
104 return thisT();
105 }
106
Eric Anderson6122daf2015-09-03 12:14:30 -0700107 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700108 public final T intercept(ClientInterceptor... interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700109 return intercept(Arrays.asList(interceptors));
110 }
111
Kun Zhang942f4c92015-09-04 17:21:44 -0700112 @Override
113 public final T nameResolverFactory(NameResolver.Factory resolverFactory) {
114 Preconditions.checkState(directServerAddress == null,
115 "directServerAddress is set (%s), which forbids the use of NameResolverFactory",
116 directServerAddress);
117 this.nameResolverFactory = resolverFactory;
118 return thisT();
119 }
120
121 @Override
122 public final T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory) {
123 Preconditions.checkState(directServerAddress == null,
124 "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory",
125 directServerAddress);
126 this.loadBalancerFactory = loadBalancerFactory;
127 return thisT();
128 }
129
nmittlerb687bdc2015-08-31 16:13:39 -0700130 private T thisT() {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700131 @SuppressWarnings("unchecked")
nmittlerb687bdc2015-08-31 16:13:39 -0700132 T thisT = (T) this;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700133 return thisT;
ejona7235a392015-01-13 13:38:54 -0800134 }
135
Eric Anderson6122daf2015-09-03 12:14:30 -0700136 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700137 public final T userAgent(String userAgent) {
nmittler8c1d38a2015-06-01 08:31:00 -0700138 this.userAgent = userAgent;
nmittlerb687bdc2015-08-31 16:13:39 -0700139 return thisT();
nmittler8c1d38a2015-06-01 08:31:00 -0700140 }
141
Eric Anderson6122daf2015-09-03 12:14:30 -0700142 @Override
Kun Zhang942f4c92015-09-04 17:21:44 -0700143 public final T overrideAuthority(String authority) {
144 this.authorityOverride = checkAuthority(authority);
145 return thisT();
146 }
147
148 /**
149 * Verifies the authority is valid. This method exists as an escape hatch for putting in an
150 * authority that is valid, but would fail the default validation provided by this
151 * implementation.
152 */
153 protected String checkAuthority(String authority) {
154 return GrpcUtil.checkAuthority(authority);
155 }
156
157 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700158 public ManagedChannelImpl build() {
Kun Zhang942f4c92015-09-04 17:21:44 -0700159 ClientTransportFactory transportFactory = new AuthorityOverridingTransportFactory(
160 buildTransportFactory(), authorityOverride);
161 return new ManagedChannelImpl(
162 target,
163 // TODO(carl-mastrangelo): Allow clients to pass this in
164 new ExponentialBackoffPolicy.Provider(),
Kun Zhangefac6792015-10-22 14:59:44 -0700165 nameResolverFactory == null ? NameResolverRegistry.getDefaultRegistry()
166 : nameResolverFactory,
Kun Zhangedd57c92015-10-27 12:47:29 -0700167 getNameResolverParams(),
Kun Zhangefac6792015-10-22 14:59:44 -0700168 loadBalancerFactory == null ? SimpleLoadBalancerFactory.getInstance()
169 : loadBalancerFactory,
Kun Zhang942f4c92015-09-04 17:21:44 -0700170 transportFactory, executor, userAgent, interceptors);
zhangkun8d6d12e2014-10-15 13:04:19 -0700171 }
172
173 /**
Kun Zhangedd57c92015-10-27 12:47:29 -0700174 * Subclasses should override this method to provide the {@link ClientTransportFactory}
175 * appropriate for this channel. This method is meant for Transport implementors and should not
176 * be used by normal users.
zhangkun8d6d12e2014-10-15 13:04:19 -0700177 */
nmittler777e9282015-08-19 10:01:52 -0700178 protected abstract ClientTransportFactory buildTransportFactory();
Kun Zhang942f4c92015-09-04 17:21:44 -0700179
Kun Zhangedd57c92015-10-27 12:47:29 -0700180 /**
181 * Subclasses can override this method to provide additional parameters to {@link
182 * NameResolver.Factory#newNameResolver}. The default implementation returns {@link
183 * Attributes.EMPTY}.
184 */
185 protected Attributes getNameResolverParams() {
186 return Attributes.EMPTY;
187 }
188
Kun Zhang942f4c92015-09-04 17:21:44 -0700189 private static class AuthorityOverridingTransportFactory implements ClientTransportFactory {
190 final ClientTransportFactory factory;
191 @Nullable final String authorityOverride;
192
193 AuthorityOverridingTransportFactory(
194 ClientTransportFactory factory, @Nullable String authorityOverride) {
195 this.factory = factory;
196 this.authorityOverride = authorityOverride;
197 }
198
199 @Override
200 public ClientTransport newClientTransport(SocketAddress serverAddress, String authority) {
201 return factory.newClientTransport(
202 serverAddress, authorityOverride != null ? authorityOverride : authority);
203 }
204
205 @Override
206 public int referenceCount() {
207 return factory.referenceCount();
208 }
209
210 @Override
211 public ReferenceCounted retain() {
212 factory.retain();
213 return this;
214 }
215
216 @Override
217 public ReferenceCounted release() {
218 factory.release();
219 return this;
220 }
221 }
222
223 private static class DirectAddressNameResolverFactory extends NameResolver.Factory {
224 final SocketAddress address;
225 final String authority;
226
227 DirectAddressNameResolverFactory(SocketAddress address, String authority) {
228 this.address = address;
229 this.authority = authority;
230 }
231
232 @Override
Kun Zhangedd57c92015-10-27 12:47:29 -0700233 public NameResolver newNameResolver(URI notUsedUri, Attributes params) {
Kun Zhang942f4c92015-09-04 17:21:44 -0700234 return new NameResolver() {
235 @Override
236 public String getServiceAuthority() {
237 return authority;
238 }
239
240 @Override
241 public void start(final Listener listener) {
242 listener.onUpdate(
243 Collections.singletonList(new ResolvedServerInfo(address, Attributes.EMPTY)),
244 Attributes.EMPTY);
245 }
246
247 @Override
248 public void shutdown() {}
249 };
250 }
251 }
zhangkun8d6d12e2014-10-15 13:04:19 -0700252}