blob: 5f4b4431851fa32f9fb27d1e4de922c0d4ff2a97 [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;
Kun Zhang527fd672016-06-17 09:47:41 -070035import static com.google.common.base.Preconditions.checkArgument;
Carl Mastrangelo82a79d82015-12-07 14:40:11 -080036
Kun Zhang631a9d52016-06-02 16:47:36 -070037import com.google.common.annotations.VisibleForTesting;
Kun Zhang942f4c92015-09-04 17:21:44 -070038import com.google.common.base.Preconditions;
buchgr602473d2015-11-11 12:53:08 +010039import com.google.common.util.concurrent.MoreExecutors;
Kun Zhangcce8eac2017-01-05 10:48:13 -080040import com.google.instrumentation.stats.Stats;
41import com.google.instrumentation.stats.StatsContextFactory;
Kun Zhang49bde542017-04-25 13:53:29 -070042import com.google.instrumentation.trace.Tracing;
Kun Zhang942f4c92015-09-04 17:21:44 -070043import io.grpc.Attributes;
44import io.grpc.ClientInterceptor;
Carl Mastrangelo82a79d82015-12-07 14:40:11 -080045import io.grpc.CompressorRegistry;
46import io.grpc.DecompressorRegistry;
Kun Zhang418d52d2017-03-22 18:29:31 -070047import io.grpc.EquivalentAddressGroup;
Kun Zhanga9bd9472017-02-21 17:11:03 -080048import io.grpc.LoadBalancer;
Kun Zhangd17a7b52017-01-10 15:30:12 -080049import io.grpc.ManagedChannel;
Kun Zhang942f4c92015-09-04 17:21:44 -070050import io.grpc.ManagedChannelBuilder;
51import io.grpc.NameResolver;
Eric Anderson56a29382016-06-11 11:55:49 -070052import io.grpc.NameResolverProvider;
Kun Zhanga9bd9472017-02-21 17:11:03 -080053import io.grpc.PickFirstBalancerFactory;
Kun Zhang942f4c92015-09-04 17:21:44 -070054import java.net.SocketAddress;
55import java.net.URI;
Kun Zhang631a9d52016-06-02 16:47:36 -070056import java.net.URISyntaxException;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070057import java.util.ArrayList;
58import java.util.Arrays;
Kun Zhang942f4c92015-09-04 17:21:44 -070059import java.util.Collections;
Eric Anderson0df3d5e2015-06-25 18:00:00 -070060import java.util.List;
Louis Ryan6a782a02015-09-03 14:27:48 -070061import java.util.concurrent.Executor;
Kun Zhang527fd672016-06-17 09:47:41 -070062import java.util.concurrent.TimeUnit;
zhangkun8d6d12e2014-10-15 13:04:19 -070063import javax.annotation.Nullable;
64
65/**
66 * The base class for channel builders.
nathanmittler0304b3d2014-10-24 13:39:13 -070067 *
nmittlerb687bdc2015-08-31 16:13:39 -070068 * @param <T> The concrete type of this builder.
zhangkun8d6d12e2014-10-15 13:04:19 -070069 */
nmittlerb687bdc2015-08-31 16:13:39 -070070public abstract class AbstractManagedChannelImplBuilder
71 <T extends AbstractManagedChannelImplBuilder<T>> extends ManagedChannelBuilder<T> {
Kun Zhang16247152015-12-08 17:52:05 -080072 private static final String DIRECT_ADDRESS_SCHEME = "directaddress";
Eric Andersonaeeebb72014-12-19 16:41:03 -080073
Kun Zhang527fd672016-06-17 09:47:41 -070074 /**
75 * An idle timeout larger than this would disable idle mode.
76 */
77 @VisibleForTesting
78 static final long IDLE_MODE_MAX_TIMEOUT_DAYS = 30;
79
80 /**
Kun Zhangd74091f2016-09-16 22:34:27 -070081 * The default idle timeout.
82 */
83 @VisibleForTesting
84 static final long IDLE_MODE_DEFAULT_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(30);
85
86 /**
Kun Zhang527fd672016-06-17 09:47:41 -070087 * An idle timeout smaller than this would be capped to it.
88 */
89 @VisibleForTesting
90 static final long IDLE_MODE_MIN_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(1);
91
ejona7235a392015-01-13 13:38:54 -080092 @Nullable
Louis Ryan6a782a02015-09-03 14:27:48 -070093 private Executor executor;
Kun Zhangd17a7b52017-01-10 15:30:12 -080094
Eric Anderson0df3d5e2015-06-25 18:00:00 -070095 private final List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
zhangkun8d6d12e2014-10-15 13:04:19 -070096
Kun Zhangefac6792015-10-22 14:59:44 -070097 private final String target;
Kun Zhang942f4c92015-09-04 17:21:44 -070098
99 @Nullable
100 private final SocketAddress directServerAddress;
101
nmittler8c1d38a2015-06-01 08:31:00 -0700102 @Nullable
103 private String userAgent;
104
Kun Zhang942f4c92015-09-04 17:21:44 -0700105 @Nullable
106 private String authorityOverride;
107
108 @Nullable
109 private NameResolver.Factory nameResolverFactory;
110
Kun Zhanga9bd9472017-02-21 17:11:03 -0800111 private LoadBalancer.Factory loadBalancerFactory;
Kun Zhang942f4c92015-09-04 17:21:44 -0700112
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800113 @Nullable
114 private DecompressorRegistry decompressorRegistry;
115
116 @Nullable
117 private CompressorRegistry compressorRegistry;
118
Kun Zhangd74091f2016-09-16 22:34:27 -0700119 private long idleTimeoutMillis = IDLE_MODE_DEFAULT_TIMEOUT_MILLIS;
Kun Zhang527fd672016-06-17 09:47:41 -0700120
Carl Mastrangelofdd062c2016-10-26 16:55:41 -0700121 private int maxInboundMessageSize = GrpcUtil.DEFAULT_MAX_MESSAGE_SIZE;
122
Kun Zhangbe74e972017-04-26 10:50:55 -0700123 private boolean enableStatsTagPropagation;
124 private boolean enableTracing;
125
Carl Mastrangelofdd062c2016-10-26 16:55:41 -0700126 // Can be overriden by subclasses.
127 @Override
128 public T maxInboundMessageSize(int max) {
129 checkArgument(max >= 0, "negative max");
130 maxInboundMessageSize = max;
131 return thisT();
132 }
133
134 protected final int maxInboundMessageSize() {
135 return maxInboundMessageSize;
136 }
137
Kun Zhang132f7a92016-10-06 17:15:24 -0700138 @Nullable
Kun Zhangcce8eac2017-01-05 10:48:13 -0800139 private StatsContextFactory statsFactory;
Kun Zhang132f7a92016-10-06 17:15:24 -0700140
Kun Zhangefac6792015-10-22 14:59:44 -0700141 protected AbstractManagedChannelImplBuilder(String target) {
Carl Mastrangelo12854772016-08-12 14:52:00 -0700142 this.target = Preconditions.checkNotNull(target, "target");
Kun Zhang942f4c92015-09-04 17:21:44 -0700143 this.directServerAddress = null;
144 }
145
Kun Zhang631a9d52016-06-02 16:47:36 -0700146 /**
147 * Returns a target string for the SocketAddress. It is only used as a placeholder, because
148 * DirectAddressNameResolverFactory will not actually try to use it. However, it must be a valid
149 * URI.
150 */
151 @VisibleForTesting
152 static String makeTargetStringForDirectAddress(SocketAddress address) {
153 try {
154 return new URI(DIRECT_ADDRESS_SCHEME, "", "/" + address, null).toString();
155 } catch (URISyntaxException e) {
156 // It should not happen.
157 throw new RuntimeException(e);
158 }
159 }
160
Kun Zhang942f4c92015-09-04 17:21:44 -0700161 protected AbstractManagedChannelImplBuilder(SocketAddress directServerAddress, String authority) {
Kun Zhang631a9d52016-06-02 16:47:36 -0700162 this.target = makeTargetStringForDirectAddress(directServerAddress);
Kun Zhang942f4c92015-09-04 17:21:44 -0700163 this.directServerAddress = directServerAddress;
164 this.nameResolverFactory = new DirectAddressNameResolverFactory(directServerAddress, authority);
165 }
166
Eric Anderson6122daf2015-09-03 12:14:30 -0700167 @Override
buchgr602473d2015-11-11 12:53:08 +0100168 public final T directExecutor() {
169 return executor(MoreExecutors.directExecutor());
170 }
171
172 @Override
Louis Ryan6a782a02015-09-03 14:27:48 -0700173 public final T executor(Executor executor) {
nmittler777e9282015-08-19 10:01:52 -0700174 this.executor = executor;
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700175 return thisT();
176 }
177
Eric Anderson6122daf2015-09-03 12:14:30 -0700178 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700179 public final T intercept(List<ClientInterceptor> interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700180 this.interceptors.addAll(interceptors);
181 return thisT();
182 }
183
Eric Anderson6122daf2015-09-03 12:14:30 -0700184 @Override
nmittlerb687bdc2015-08-31 16:13:39 -0700185 public final T intercept(ClientInterceptor... interceptors) {
Eric Anderson0df3d5e2015-06-25 18:00:00 -0700186 return intercept(Arrays.asList(interceptors));
187 }
188
Kun Zhang942f4c92015-09-04 17:21:44 -0700189 @Override
190 public final T nameResolverFactory(NameResolver.Factory resolverFactory) {
191 Preconditions.checkState(directServerAddress == null,
192 "directServerAddress is set (%s), which forbids the use of NameResolverFactory",
193 directServerAddress);
194 this.nameResolverFactory = resolverFactory;
195 return thisT();
196 }
197
198 @Override
Kun Zhanga9bd9472017-02-21 17:11:03 -0800199 public final T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory) {
Kun Zhang942f4c92015-09-04 17:21:44 -0700200 Preconditions.checkState(directServerAddress == null,
Kun Zhanga9bd9472017-02-21 17:11:03 -0800201 "directServerAddress is set (%s), which forbids the use of LoadBalancer.Factory",
Kun Zhang942f4c92015-09-04 17:21:44 -0700202 directServerAddress);
203 this.loadBalancerFactory = loadBalancerFactory;
Kun Zhangd17a7b52017-01-10 15:30:12 -0800204 return thisT();
205 }
206
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800207 @Override
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800208 public final T decompressorRegistry(DecompressorRegistry registry) {
209 this.decompressorRegistry = registry;
210 return thisT();
211 }
212
213 @Override
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800214 public final T compressorRegistry(CompressorRegistry registry) {
215 this.compressorRegistry = registry;
216 return thisT();
217 }
218
Eric Anderson6122daf2015-09-03 12:14:30 -0700219 @Override
Carl Mastrangelo1cc76d82016-05-24 16:29:26 -0700220 public final T userAgent(@Nullable String userAgent) {
nmittler8c1d38a2015-06-01 08:31:00 -0700221 this.userAgent = userAgent;
nmittlerb687bdc2015-08-31 16:13:39 -0700222 return thisT();
nmittler8c1d38a2015-06-01 08:31:00 -0700223 }
224
Eric Anderson6122daf2015-09-03 12:14:30 -0700225 @Override
Kun Zhang942f4c92015-09-04 17:21:44 -0700226 public final T overrideAuthority(String authority) {
227 this.authorityOverride = checkAuthority(authority);
228 return thisT();
229 }
230
Kun Zhang527fd672016-06-17 09:47:41 -0700231 @Override
232 public final T idleTimeout(long value, TimeUnit unit) {
233 checkArgument(value > 0, "idle timeout is %s, but must be positive", value);
234 // We convert to the largest unit to avoid overflow
235 if (unit.toDays(value) >= IDLE_MODE_MAX_TIMEOUT_DAYS) {
236 // This disables idle mode
Kun Zhanga9bd9472017-02-21 17:11:03 -0800237 this.idleTimeoutMillis = ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE;
Kun Zhang527fd672016-06-17 09:47:41 -0700238 } else {
239 this.idleTimeoutMillis = Math.max(unit.toMillis(value), IDLE_MODE_MIN_TIMEOUT_MILLIS);
240 }
241 return thisT();
242 }
243
Kun Zhang132f7a92016-10-06 17:15:24 -0700244 /**
Kun Zhang737cd162017-01-20 17:20:44 -0800245 * Override the default stats implementation.
Kun Zhang132f7a92016-10-06 17:15:24 -0700246 */
247 @VisibleForTesting
Kun Zhang903197b2017-04-07 11:03:24 -0700248 protected final T statsContextFactory(StatsContextFactory statsFactory) {
Kun Zhangcce8eac2017-01-05 10:48:13 -0800249 this.statsFactory = statsFactory;
Kun Zhang132f7a92016-10-06 17:15:24 -0700250 return thisT();
251 }
252
Kun Zhang903197b2017-04-07 11:03:24 -0700253 /**
254 * Indicates whether this transport will record stats with {@link ClientStreamTracer}.
255 *
256 * <p>By default it returns {@code true}. If the transport doesn't record stats, it may override
257 * this method to return {@code false} so that the builder won't install the Census interceptor.
258 *
259 * <p>If it returns true when it shouldn't be, Census will receive incomplete stats.
260 */
261 protected boolean recordsStats() {
262 return true;
263 }
264
Kun Zhang527fd672016-06-17 09:47:41 -0700265 @VisibleForTesting
266 final long getIdleTimeoutMillis() {
267 return idleTimeoutMillis;
268 }
269
Kun Zhang942f4c92015-09-04 17:21:44 -0700270 /**
271 * Verifies the authority is valid. This method exists as an escape hatch for putting in an
272 * authority that is valid, but would fail the default validation provided by this
273 * implementation.
274 */
275 protected String checkAuthority(String authority) {
276 return GrpcUtil.checkAuthority(authority);
277 }
278
Kun Zhangbe74e972017-04-26 10:50:55 -0700279 /**
280 * Set it to true to propagate the stats tags on the wire. This will be deleted assuming always
281 * enabled once the instrumentation-java wire format is stabilized.
282 */
283 @Deprecated
284 public void setEnableStatsTagPropagation(boolean enabled) {
285 this.enableStatsTagPropagation = enabled;
286 }
287
288 /**
289 * Set it to true to record traces and propagate tracing information on the wire. This will be
290 * deleted assuming always enabled once the instrumentation-java wire format is stabilized.
291 */
292 @Deprecated
293 public void setEnableTracing(boolean enabled) {
294 this.enableTracing = enabled;
295 }
296
Kun Zhang942f4c92015-09-04 17:21:44 -0700297 @Override
Kun Zhangd17a7b52017-01-10 15:30:12 -0800298 public ManagedChannel build() {
Sky Ao1d8aefa2016-04-18 23:43:30 +0800299 ClientTransportFactory transportFactory = buildTransportFactory();
300 if (authorityOverride != null) {
301 transportFactory = new AuthorityOverridingTransportFactory(
302 transportFactory, authorityOverride);
303 }
Eric Andersonbfcb04c2016-07-11 10:02:23 -0700304 NameResolver.Factory nameResolverFactory = this.nameResolverFactory;
305 if (nameResolverFactory == null) {
306 // Avoid loading the provider unless necessary, as a way to workaround a possibly-costly
307 // and poorly optimized getResource() call on Android. If any other piece of code calls
308 // getResource(), then this shouldn't be a problem unless called on the UI thread.
309 nameResolverFactory = NameResolverProvider.asFactory();
310 }
Kun Zhang903197b2017-04-07 11:03:24 -0700311
Kun Zhang49bde542017-04-25 13:53:29 -0700312 List<ClientInterceptor> effectiveInterceptors =
313 new ArrayList<ClientInterceptor>(this.interceptors);
Kun Zhangbe74e972017-04-26 10:50:55 -0700314 if (recordsStats()) {
Kun Zhang903197b2017-04-07 11:03:24 -0700315 StatsContextFactory statsCtxFactory =
316 this.statsFactory != null ? this.statsFactory : Stats.getStatsContextFactory();
317 if (statsCtxFactory != null) {
Kun Zhang49bde542017-04-25 13:53:29 -0700318 CensusStatsModule censusStats =
Kun Zhangbe74e972017-04-26 10:50:55 -0700319 new CensusStatsModule(
320 statsCtxFactory, GrpcUtil.STOPWATCH_SUPPLIER, enableStatsTagPropagation);
Kun Zhang903197b2017-04-07 11:03:24 -0700321 // First interceptor runs last (see ClientInterceptors.intercept()), so that no
322 // other interceptor can override the tracer factory we set in CallOptions.
Kun Zhang49bde542017-04-25 13:53:29 -0700323 effectiveInterceptors.add(0, censusStats.getClientInterceptor());
Kun Zhang903197b2017-04-07 11:03:24 -0700324 }
325 }
Kun Zhangbe74e972017-04-26 10:50:55 -0700326 if (enableTracing) {
Kun Zhang49bde542017-04-25 13:53:29 -0700327 CensusTracingModule censusTracing =
328 new CensusTracingModule(Tracing.getTracer(), Tracing.getBinaryPropagationHandler());
329 effectiveInterceptors.add(0, censusTracing.getClientInterceptor());
330 }
331
Kun Zhanga9bd9472017-02-21 17:11:03 -0800332 return new ManagedChannelImpl(
Kun Zhanga6b1d892017-02-21 14:26:23 -0800333 target,
334 // TODO(carl-mastrangelo): Allow clients to pass this in
335 new ExponentialBackoffPolicy.Provider(),
336 nameResolverFactory,
337 getNameResolverParams(),
Kun Zhanga9bd9472017-02-21 17:11:03 -0800338 firstNonNull(loadBalancerFactory, PickFirstBalancerFactory.getInstance()),
Kun Zhanga6b1d892017-02-21 14:26:23 -0800339 transportFactory,
340 firstNonNull(decompressorRegistry, DecompressorRegistry.getDefaultInstance()),
341 firstNonNull(compressorRegistry, CompressorRegistry.getDefaultInstance()),
342 SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE),
343 getExecutorPool(executor),
344 SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR),
Kun Zhanga9bd9472017-02-21 17:11:03 -0800345 GrpcUtil.STOPWATCH_SUPPLIER,
346 idleTimeoutMillis,
347 userAgent,
Kun Zhang49bde542017-04-25 13:53:29 -0700348 effectiveInterceptors);
zhangkun8d6d12e2014-10-15 13:04:19 -0700349 }
350
351 /**
Kun Zhangedd57c92015-10-27 12:47:29 -0700352 * Subclasses should override this method to provide the {@link ClientTransportFactory}
353 * appropriate for this channel. This method is meant for Transport implementors and should not
354 * be used by normal users.
zhangkun8d6d12e2014-10-15 13:04:19 -0700355 */
nmittler777e9282015-08-19 10:01:52 -0700356 protected abstract ClientTransportFactory buildTransportFactory();
Kun Zhang942f4c92015-09-04 17:21:44 -0700357
Kun Zhangedd57c92015-10-27 12:47:29 -0700358 /**
359 * Subclasses can override this method to provide additional parameters to {@link
360 * NameResolver.Factory#newNameResolver}. The default implementation returns {@link
Carl Mastrangelo82a79d82015-12-07 14:40:11 -0800361 * Attributes#EMPTY}.
Kun Zhangedd57c92015-10-27 12:47:29 -0700362 */
363 protected Attributes getNameResolverParams() {
364 return Attributes.EMPTY;
365 }
366
Kun Zhangd17a7b52017-01-10 15:30:12 -0800367 private static ObjectPool<? extends Executor> getExecutorPool(final @Nullable Executor executor) {
368 if (executor != null) {
369 return new ObjectPool<Executor>() {
370 @Override
371 public Executor getObject() {
372 return executor;
373 }
374
375 @Override
376 public Executor returnObject(Object returned) {
377 return null;
378 }
379 };
380 } else {
381 return SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR);
382 }
383 }
384
Kun Zhang942f4c92015-09-04 17:21:44 -0700385 private static class AuthorityOverridingTransportFactory implements ClientTransportFactory {
386 final ClientTransportFactory factory;
Sky Ao1d8aefa2016-04-18 23:43:30 +0800387 final String authorityOverride;
Kun Zhang942f4c92015-09-04 17:21:44 -0700388
389 AuthorityOverridingTransportFactory(
Sky Ao1d8aefa2016-04-18 23:43:30 +0800390 ClientTransportFactory factory, String authorityOverride) {
391 this.factory = Preconditions.checkNotNull(factory, "factory should not be null");
392 this.authorityOverride = Preconditions.checkNotNull(
393 authorityOverride, "authorityOverride should not be null");
Kun Zhang942f4c92015-09-04 17:21:44 -0700394 }
395
396 @Override
Kun Zhang432cec72016-05-29 14:43:10 -0700397 public ConnectionClientTransport newClientTransport(SocketAddress serverAddress,
Carl Mastrangelo1cc76d82016-05-24 16:29:26 -0700398 String authority, @Nullable String userAgent) {
399 return factory.newClientTransport(serverAddress, authorityOverride, userAgent);
Kun Zhang942f4c92015-09-04 17:21:44 -0700400 }
401
402 @Override
buchgr3c68c052016-03-17 00:14:43 +0100403 public void close() {
404 factory.close();
Kun Zhang942f4c92015-09-04 17:21:44 -0700405 }
406 }
407
408 private static class DirectAddressNameResolverFactory extends NameResolver.Factory {
409 final SocketAddress address;
410 final String authority;
411
412 DirectAddressNameResolverFactory(SocketAddress address, String authority) {
413 this.address = address;
414 this.authority = authority;
415 }
416
417 @Override
Kun Zhangedd57c92015-10-27 12:47:29 -0700418 public NameResolver newNameResolver(URI notUsedUri, Attributes params) {
Kun Zhang942f4c92015-09-04 17:21:44 -0700419 return new NameResolver() {
420 @Override
421 public String getServiceAuthority() {
422 return authority;
423 }
424
425 @Override
426 public void start(final Listener listener) {
Kun Zhang418d52d2017-03-22 18:29:31 -0700427 listener.onAddresses(
428 Collections.singletonList(new EquivalentAddressGroup(address)),
Kun Zhang942f4c92015-09-04 17:21:44 -0700429 Attributes.EMPTY);
430 }
431
432 @Override
433 public void shutdown() {}
434 };
435 }
Kun Zhang16247152015-12-08 17:52:05 -0800436
437 @Override
438 public String getDefaultScheme() {
439 return DIRECT_ADDRESS_SCHEME;
440 }
Kun Zhang942f4c92015-09-04 17:21:44 -0700441 }
Carl Mastrangelo84934982017-01-11 12:46:47 -0800442
443 /**
444 * Returns the correctly typed version of the builder.
445 */
446 private T thisT() {
447 @SuppressWarnings("unchecked")
448 T thisT = (T) this;
449 return thisT;
450 }
zhangkun8d6d12e2014-10-15 13:04:19 -0700451}