blob: b2d47667815bf4c3d12b2c7de3204823f564eb91 [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;
38import io.grpc.DnsNameResolverFactory;
39import io.grpc.Internal;
40import io.grpc.LoadBalancer;
41import io.grpc.ManagedChannelBuilder;
42import io.grpc.NameResolver;
43import 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 Zhang942f4c92015-09-04 17:21:44 -070068 private final URI target;
69
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
85 protected AbstractManagedChannelImplBuilder(URI target) {
86 this.target = Preconditions.checkNotNull(target);
87 this.directServerAddress = null;
88 }
89
90 protected AbstractManagedChannelImplBuilder(SocketAddress directServerAddress, String authority) {
91 this.target = URI.create("direct-address:///" + directServerAddress);
92 this.directServerAddress = directServerAddress;
93 this.nameResolverFactory = new DirectAddressNameResolverFactory(directServerAddress, authority);
94 }
95
Eric Anderson6122daf2015-09-03 12:14:30 -070096 @Override
Louis Ryan6a782a02015-09-03 14:27:48 -070097 public final T executor(Executor executor) {
nmittler777e9282015-08-19 10:01:52 -070098 this.executor = executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070099 return thisT();
100 }
101
Eric Anderson6122daf2015-09-03 12:14:30 -0700102 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700103 public final T intercept(List<ClientInterceptor> interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700104 this.interceptors.addAll(interceptors);
105 return thisT();
106 }
107
Eric Anderson6122daf2015-09-03 12:14:30 -0700108 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700109 public final T intercept(ClientInterceptor... interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700110 return intercept(Arrays.asList(interceptors));
111 }
112
Kun Zhang942f4c92015-09-04 17:21:44 -0700113 @Override
114 public final T nameResolverFactory(NameResolver.Factory resolverFactory) {
115 Preconditions.checkState(directServerAddress == null,
116 "directServerAddress is set (%s), which forbids the use of NameResolverFactory",
117 directServerAddress);
118 this.nameResolverFactory = resolverFactory;
119 return thisT();
120 }
121
122 @Override
123 public final T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory) {
124 Preconditions.checkState(directServerAddress == null,
125 "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory",
126 directServerAddress);
127 this.loadBalancerFactory = loadBalancerFactory;
128 return thisT();
129 }
130
nmittlerb687bdc2015-08-31 16:13:39 -0700131 private T thisT() {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700132 @SuppressWarnings("unchecked")
nmittlerb687bdc2015-08-31 16:13:39 -0700133 T thisT = (T) this;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700134 return thisT;
ejona7235a392015-01-13 13:38:54 -0800135 }
136
Eric Anderson6122daf2015-09-03 12:14:30 -0700137 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700138 public final T userAgent(String userAgent) {
nmittler8c1d38a2015-06-01 08:31:00 -0700139 this.userAgent = userAgent;
nmittlerb687bdc2015-08-31 16:13:39 -0700140 return thisT();
nmittler8c1d38a2015-06-01 08:31:00 -0700141 }
142
Eric Anderson6122daf2015-09-03 12:14:30 -0700143 @Override
Kun Zhang942f4c92015-09-04 17:21:44 -0700144 public final T overrideAuthority(String authority) {
145 this.authorityOverride = checkAuthority(authority);
146 return thisT();
147 }
148
149 /**
150 * Verifies the authority is valid. This method exists as an escape hatch for putting in an
151 * authority that is valid, but would fail the default validation provided by this
152 * implementation.
153 */
154 protected String checkAuthority(String authority) {
155 return GrpcUtil.checkAuthority(authority);
156 }
157
158 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700159 public ManagedChannelImpl build() {
Kun Zhang942f4c92015-09-04 17:21:44 -0700160 ClientTransportFactory transportFactory = new AuthorityOverridingTransportFactory(
161 buildTransportFactory(), authorityOverride);
162 return new ManagedChannelImpl(
163 target,
164 // TODO(carl-mastrangelo): Allow clients to pass this in
165 new ExponentialBackoffPolicy.Provider(),
166 // TODO(zhangkun83): use a NameResolver registry for the "nameResolverFactory == null" case
167 nameResolverFactory == null ? DnsNameResolverFactory.getInstance() : nameResolverFactory,
168 loadBalancerFactory == null ? SimpleLoadBalancerFactory.getInstance() : loadBalancerFactory,
169 transportFactory, executor, userAgent, interceptors);
zhangkun8d6d12e2014-10-15 13:04:19 -0700170 }
171
172 /**
nmittler777e9282015-08-19 10:01:52 -0700173 * Children of AbstractChannelBuilder should override this method to provide the
174 * {@link ClientTransportFactory} appropriate for this channel. This method is meant for
175 * Transport implementors and should not be used by normal users.
zhangkun8d6d12e2014-10-15 13:04:19 -0700176 */
Kun Zhang0eb98622015-08-11 11:06:50 -0700177 @Internal
nmittler777e9282015-08-19 10:01:52 -0700178 protected abstract ClientTransportFactory buildTransportFactory();
Kun Zhang942f4c92015-09-04 17:21:44 -0700179
180 private static class AuthorityOverridingTransportFactory implements ClientTransportFactory {
181 final ClientTransportFactory factory;
182 @Nullable final String authorityOverride;
183
184 AuthorityOverridingTransportFactory(
185 ClientTransportFactory factory, @Nullable String authorityOverride) {
186 this.factory = factory;
187 this.authorityOverride = authorityOverride;
188 }
189
190 @Override
191 public ClientTransport newClientTransport(SocketAddress serverAddress, String authority) {
192 return factory.newClientTransport(
193 serverAddress, authorityOverride != null ? authorityOverride : authority);
194 }
195
196 @Override
197 public int referenceCount() {
198 return factory.referenceCount();
199 }
200
201 @Override
202 public ReferenceCounted retain() {
203 factory.retain();
204 return this;
205 }
206
207 @Override
208 public ReferenceCounted release() {
209 factory.release();
210 return this;
211 }
212 }
213
214 private static class DirectAddressNameResolverFactory extends NameResolver.Factory {
215 final SocketAddress address;
216 final String authority;
217
218 DirectAddressNameResolverFactory(SocketAddress address, String authority) {
219 this.address = address;
220 this.authority = authority;
221 }
222
223 @Override
224 public NameResolver newNameResolver(URI notUsedUri) {
225 return new NameResolver() {
226 @Override
227 public String getServiceAuthority() {
228 return authority;
229 }
230
231 @Override
232 public void start(final Listener listener) {
233 listener.onUpdate(
234 Collections.singletonList(new ResolvedServerInfo(address, Attributes.EMPTY)),
235 Attributes.EMPTY);
236 }
237
238 @Override
239 public void shutdown() {}
240 };
241 }
242 }
zhangkun8d6d12e2014-10-15 13:04:19 -0700243}