1 /* 2 * Copyright 2015 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc; 18 19 import com.google.common.base.Preconditions; 20 import java.util.List; 21 import java.util.concurrent.Executor; 22 import java.util.concurrent.TimeUnit; 23 24 /** 25 * A builder for {@link ManagedChannel} instances. 26 * 27 * @param <T> The concrete type of this builder. 28 */ 29 public abstract class ManagedChannelBuilder<T extends ManagedChannelBuilder<T>> { 30 /** 31 * Creates a channel with the target's address and port number. 32 * 33 * @see #forTarget(String) 34 * @since 1.0.0 35 */ forAddress(String name, int port)36 public static ManagedChannelBuilder<?> forAddress(String name, int port) { 37 return ManagedChannelProvider.provider().builderForAddress(name, port); 38 } 39 40 /** 41 * Creates a channel with a target string, which can be either a valid {@link 42 * NameResolver}-compliant URI, or an authority string. 43 * 44 * <p>A {@code NameResolver}-compliant URI is an absolute hierarchical URI as defined by {@link 45 * java.net.URI}. Example URIs: 46 * <ul> 47 * <li>{@code "dns:///foo.googleapis.com:8080"}</li> 48 * <li>{@code "dns:///foo.googleapis.com"}</li> 49 * <li>{@code "dns:///%5B2001:db8:85a3:8d3:1319:8a2e:370:7348%5D:443"}</li> 50 * <li>{@code "dns://8.8.8.8/foo.googleapis.com:8080"}</li> 51 * <li>{@code "dns://8.8.8.8/foo.googleapis.com"}</li> 52 * <li>{@code "zookeeper://zk.example.com:9900/example_service"}</li> 53 * </ul> 54 * 55 * <p>An authority string will be converted to a {@code NameResolver}-compliant URI, which has 56 * {@code "dns"} as the scheme, no authority, and the original authority string as its path after 57 * properly escaped. Example authority strings: 58 * <ul> 59 * <li>{@code "localhost"}</li> 60 * <li>{@code "127.0.0.1"}</li> 61 * <li>{@code "localhost:8080"}</li> 62 * <li>{@code "foo.googleapis.com:8080"}</li> 63 * <li>{@code "127.0.0.1:8080"}</li> 64 * <li>{@code "[2001:db8:85a3:8d3:1319:8a2e:370:7348]"}</li> 65 * <li>{@code "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443"}</li> 66 * </ul> 67 * 68 * @since 1.0.0 69 */ forTarget(String target)70 public static ManagedChannelBuilder<?> forTarget(String target) { 71 return ManagedChannelProvider.provider().builderForTarget(target); 72 } 73 74 /** 75 * Execute application code directly in the transport thread. 76 * 77 * <p>Depending on the underlying transport, using a direct executor may lead to substantial 78 * performance improvements. However, it also requires the application to not block under 79 * any circumstances. 80 * 81 * <p>Calling this method is semantically equivalent to calling {@link #executor(Executor)} and 82 * passing in a direct executor. However, this is the preferred way as it may allow the transport 83 * to perform special optimizations. 84 * 85 * @return this 86 * @since 1.0.0 87 */ directExecutor()88 public abstract T directExecutor(); 89 90 /** 91 * Provides a custom executor. 92 * 93 * <p>It's an optional parameter. If the user has not provided an executor when the channel is 94 * built, the builder will use a static cached thread pool. 95 * 96 * <p>The channel won't take ownership of the given executor. It's caller's responsibility to 97 * shut down the executor when it's desired. 98 * 99 * @return this 100 * @since 1.0.0 101 */ executor(Executor executor)102 public abstract T executor(Executor executor); 103 104 /** 105 * Adds interceptors that will be called before the channel performs its real work. This is 106 * functionally equivalent to using {@link ClientInterceptors#intercept(Channel, List)}, but while 107 * still having access to the original {@code ManagedChannel}. 108 * 109 * @return this 110 * @since 1.0.0 111 */ intercept(List<ClientInterceptor> interceptors)112 public abstract T intercept(List<ClientInterceptor> interceptors); 113 114 /** 115 * Adds interceptors that will be called before the channel performs its real work. This is 116 * functionally equivalent to using {@link ClientInterceptors#intercept(Channel, 117 * ClientInterceptor...)}, but while still having access to the original {@code ManagedChannel}. 118 * 119 * @return this 120 * @since 1.0.0 121 */ intercept(ClientInterceptor... interceptors)122 public abstract T intercept(ClientInterceptor... interceptors); 123 124 /** 125 * Provides a custom {@code User-Agent} for the application. 126 * 127 * <p>It's an optional parameter. The library will provide a user agent independent of this 128 * option. If provided, the given agent will prepend the library's user agent information. 129 * 130 * @return this 131 * @since 1.0.0 132 */ userAgent(String userAgent)133 public abstract T userAgent(String userAgent); 134 135 /** 136 * Overrides the authority used with TLS and HTTP virtual hosting. It does not change what host is 137 * actually connected to. Is commonly in the form {@code host:port}. 138 * 139 * <p>This method is intended for testing, but may safely be used outside of tests as an 140 * alternative to DNS overrides. 141 * 142 * @return this 143 * @since 1.0.0 144 */ overrideAuthority(String authority)145 public abstract T overrideAuthority(String authority); 146 147 /** 148 * Use of a plaintext connection to the server. By default a secure connection mechanism 149 * such as TLS will be used. 150 * 151 * <p>Should only be used for testing or for APIs where the use of such API or the data 152 * exchanged is not sensitive. 153 * 154 * @param skipNegotiation @{code true} if there is a priori knowledge that the endpoint supports 155 * plaintext, {@code false} if plaintext use must be negotiated. 156 * @deprecated Use {@link #usePlaintext()} instead. 157 * 158 * @throws UnsupportedOperationException if plaintext mode is not supported. 159 * @return this 160 * @since 1.0.0 161 */ 162 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1772") 163 @Deprecated usePlaintext(boolean skipNegotiation)164 public T usePlaintext(boolean skipNegotiation) { 165 throw new UnsupportedOperationException(); 166 } 167 168 /** 169 * Use of a plaintext connection to the server. By default a secure connection mechanism 170 * such as TLS will be used. 171 * 172 * <p>Should only be used for testing or for APIs where the use of such API or the data 173 * exchanged is not sensitive. 174 * 175 * <p>This assumes prior knowledge that the target of this channel is using plaintext. It will 176 * not perform HTTP/1.1 upgrades. 177 * 178 * 179 * @throws UnsupportedOperationException if plaintext mode is not supported. 180 * @return this 181 * @since 1.11.0 182 */ 183 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1772") 184 @SuppressWarnings("deprecation") usePlaintext()185 public T usePlaintext() { 186 return usePlaintext(true); 187 } 188 189 /** 190 * Makes the client use TLS. 191 * 192 * @return this 193 * @throws UnsupportedOperationException if transport security is not supported. 194 * @since 1.9.0 195 */ 196 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3713") useTransportSecurity()197 public T useTransportSecurity() { 198 throw new UnsupportedOperationException(); 199 } 200 201 /** 202 * Provides a custom {@link NameResolver.Factory} for the channel. If this method is not called, 203 * the builder will try the providers listed by {@link NameResolverProvider#providers()} for the 204 * given target. 205 * 206 * <p>This method should rarely be used, as name resolvers should provide a {@code 207 * NameResolverProvider} and users rely on service loading to find implementations in the class 208 * path. That allows application's configuration to easily choose the name resolver via the 209 * 'target' string passed to {@link ManagedChannelBuilder#forTarget(String)}. 210 * 211 * @return this 212 * @since 1.0.0 213 */ 214 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1770") nameResolverFactory(NameResolver.Factory resolverFactory)215 public abstract T nameResolverFactory(NameResolver.Factory resolverFactory); 216 217 /** 218 * Provides a custom {@link LoadBalancer.Factory} for the channel. 219 * 220 * <p>If this method is not called, the builder will use {@link PickFirstBalancerFactory} 221 * for the channel. 222 * 223 * <p>This method is implemented by all stock channel builders that 224 * are shipped with gRPC, but may not be implemented by custom channel builders, in which case 225 * this method will throw. 226 * 227 * @return this 228 * @since 1.0.0 229 */ 230 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771") loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory)231 public abstract T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory); 232 233 /** 234 * Enables full-stream decompression of inbound streams. This will cause the channel's outbound 235 * headers to advertise support for GZIP compressed streams, and gRPC servers which support the 236 * feature may respond with a GZIP compressed stream. 237 * 238 * <p>EXPERIMENTAL: This method is here to enable an experimental feature, and may be changed or 239 * removed once the feature is stable. 240 * 241 * @throws UnsupportedOperationException if unsupported 242 * @since 1.7.0 243 */ 244 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3399") enableFullStreamDecompression()245 public T enableFullStreamDecompression() { 246 throw new UnsupportedOperationException(); 247 } 248 249 /** 250 * Set the decompression registry for use in the channel. This is an advanced API call and 251 * shouldn't be used unless you are using custom message encoding. The default supported 252 * decompressors are in {@link DecompressorRegistry#getDefaultInstance}. 253 * 254 * @return this 255 * @since 1.0.0 256 */ 257 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") decompressorRegistry(DecompressorRegistry registry)258 public abstract T decompressorRegistry(DecompressorRegistry registry); 259 260 /** 261 * Set the compression registry for use in the channel. This is an advanced API call and 262 * shouldn't be used unless you are using custom message encoding. The default supported 263 * compressors are in {@link CompressorRegistry#getDefaultInstance}. 264 * 265 * @return this 266 * @since 1.0.0 267 */ 268 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") compressorRegistry(CompressorRegistry registry)269 public abstract T compressorRegistry(CompressorRegistry registry); 270 271 /** 272 * Set the duration without ongoing RPCs before going to idle mode. 273 * 274 * <p>In idle mode the channel shuts down all connections, the NameResolver and the 275 * LoadBalancer. A new RPC would take the channel out of idle mode. A channel starts in idle mode. 276 * 277 * <p>By default the channel will never go to idle mode after it leaves the initial idle 278 * mode. 279 * 280 * <p>This is an advisory option. Do not rely on any specific behavior related to this option. 281 * 282 * @return this 283 * @since 1.0.0 284 */ 285 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2022") idleTimeout(long value, TimeUnit unit)286 public abstract T idleTimeout(long value, TimeUnit unit); 287 288 /** 289 * Sets the maximum message size allowed to be received on the channel. If not called, 290 * defaults to 4 MiB. The default provides protection to clients who haven't considered the 291 * possibility of receiving large messages while trying to be large enough to not be hit in normal 292 * usage. 293 * 294 * <p>This method is advisory, and implementations may decide to not enforce this. Currently, 295 * the only known transport to not enforce this is {@code InProcessTransport}. 296 * 297 * @param bytes the maximum number of bytes a single message can be. 298 * @return this 299 * @throws IllegalArgumentException if bytes is negative. 300 * @since 1.1.0 301 */ maxInboundMessageSize(int bytes)302 public T maxInboundMessageSize(int bytes) { 303 // intentional noop rather than throw, this method is only advisory. 304 Preconditions.checkArgument(bytes >= 0, "bytes must be >= 0"); 305 return thisT(); 306 } 307 308 /** 309 * Sets the time without read activity before sending a keepalive ping. An unreasonably small 310 * value might be increased, and {@code Long.MAX_VALUE} nano seconds or an unreasonably large 311 * value will disable keepalive. Defaults to infinite. 312 * 313 * <p>Clients must receive permission from the service owner before enabling this option. 314 * Keepalives can increase the load on services and are commonly "invisible" making it hard to 315 * notice when they are causing excessive load. Clients are strongly encouraged to use only as 316 * small of a value as necessary. 317 * 318 * @throws UnsupportedOperationException if unsupported 319 * @since 1.7.0 320 */ keepAliveTime(long keepAliveTime, TimeUnit timeUnit)321 public T keepAliveTime(long keepAliveTime, TimeUnit timeUnit) { 322 throw new UnsupportedOperationException(); 323 } 324 325 /** 326 * Sets the time waiting for read activity after sending a keepalive ping. If the time expires 327 * without any read activity on the connection, the connection is considered dead. An unreasonably 328 * small value might be increased. Defaults to 20 seconds. 329 * 330 * <p>This value should be at least multiple times the RTT to allow for lost packets. 331 * 332 * @throws UnsupportedOperationException if unsupported 333 * @since 1.7.0 334 */ keepAliveTimeout(long keepAliveTimeout, TimeUnit timeUnit)335 public T keepAliveTimeout(long keepAliveTimeout, TimeUnit timeUnit) { 336 throw new UnsupportedOperationException(); 337 } 338 339 /** 340 * Sets whether keepalive will be performed when there are no outstanding RPC on a connection. 341 * Defaults to {@code false}. 342 * 343 * <p>Clients must receive permission from the service owner before enabling this option. 344 * Keepalives on unused connections can easilly accidentally consume a considerable amount of 345 * bandwidth and CPU. {@link ManagedChannelBuilder#idleTimeout idleTimeout()} should generally be 346 * used instead of this option. 347 * 348 * @throws UnsupportedOperationException if unsupported 349 * @see #keepAliveTime(long, TimeUnit) 350 * @since 1.7.0 351 */ keepAliveWithoutCalls(boolean enable)352 public T keepAliveWithoutCalls(boolean enable) { 353 throw new UnsupportedOperationException(); 354 } 355 356 /** 357 * Sets max number of retry attempts. The total number of retry attempts for each RPC will not 358 * exceed this number even if service config may allow a higher number. Setting this number to 359 * zero is not effectively the same as {@code disableRetry()} because the former does not disable 360 * <a 361 * href="https://github.com/grpc/proposal/blob/master/A6-client-retries.md#transparent-retries"> 362 * transparent retry</a>. 363 * 364 * <p>This method may not work as expected for the current release because retry is not fully 365 * implemented yet. 366 * 367 * @return this 368 * @since 1.11.0 369 */ 370 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982") maxRetryAttempts(int maxRetryAttempts)371 public T maxRetryAttempts(int maxRetryAttempts) { 372 throw new UnsupportedOperationException(); 373 } 374 375 /** 376 * Sets max number of hedged attempts. The total number of hedged attempts for each RPC will not 377 * exceed this number even if service config may allow a higher number. 378 * 379 * <p>This method may not work as expected for the current release because retry is not fully 380 * implemented yet. 381 * 382 * @return this 383 * @since 1.11.0 384 */ 385 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982") maxHedgedAttempts(int maxHedgedAttempts)386 public T maxHedgedAttempts(int maxHedgedAttempts) { 387 throw new UnsupportedOperationException(); 388 } 389 390 /** 391 * Sets the retry buffer size in bytes. If the buffer limit is exceeded, no RPC 392 * could retry at the moment, and in hedging case all hedges but one of the same RPC will cancel. 393 * The implementation may only estimate the buffer size being used rather than count the 394 * exact physical memory allocated. The method does not have any effect if retry is disabled by 395 * the client. 396 * 397 * <p>This method may not work as expected for the current release because retry is not fully 398 * implemented yet. 399 * 400 * @return this 401 * @since 1.10.0 402 */ 403 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982") retryBufferSize(long bytes)404 public T retryBufferSize(long bytes) { 405 throw new UnsupportedOperationException(); 406 } 407 408 /** 409 * Sets the per RPC buffer limit in bytes used for retry. The RPC is not retriable if its buffer 410 * limit is exceeded. The implementation may only estimate the buffer size being used rather than 411 * count the exact physical memory allocated. It does not have any effect if retry is disabled by 412 * the client. 413 * 414 * <p>This method may not work as expected for the current release because retry is not fully 415 * implemented yet. 416 * 417 * @return this 418 * @since 1.10.0 419 */ 420 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982") perRpcBufferLimit(long bytes)421 public T perRpcBufferLimit(long bytes) { 422 throw new UnsupportedOperationException(); 423 } 424 425 426 /** 427 * Disables the retry and hedging mechanism provided by the gRPC library. This is designed for the 428 * case when users have their own retry implementation and want to avoid their own retry taking 429 * place simultaneously with the gRPC library layer retry. 430 * 431 * @return this 432 * @since 1.11.0 433 */ 434 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982") disableRetry()435 public T disableRetry() { 436 throw new UnsupportedOperationException(); 437 } 438 439 /** 440 * Enables the retry and hedging mechanism provided by the gRPC library. 441 * 442 * <p>This method may not work as expected for the current release because retry is not fully 443 * implemented yet. 444 * 445 * @return this 446 * @since 1.11.0 447 */ 448 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982") enableRetry()449 public T enableRetry() { 450 throw new UnsupportedOperationException(); 451 } 452 453 /** 454 * Sets the BinaryLog object that this channel should log to. The channel does not take 455 * ownership of the object, and users are responsible for calling {@link BinaryLog#close()}. 456 * 457 * @param binaryLog the object to provide logging. 458 * @return this 459 * @since 1.13.0 460 */ 461 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4017") setBinaryLog(BinaryLog binaryLog)462 public T setBinaryLog(BinaryLog binaryLog) { 463 throw new UnsupportedOperationException(); 464 } 465 466 /** 467 * Sets the maximum number of channel trace events to keep in the tracer for each channel or 468 * subchannel. If set to 0, channel tracing is effectively disabled. 469 * 470 * @return this 471 * @since 1.13.0 472 */ 473 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4471") maxTraceEvents(int maxTraceEvents)474 public T maxTraceEvents(int maxTraceEvents) { 475 throw new UnsupportedOperationException(); 476 } 477 478 /** 479 * Builds a channel using the given parameters. 480 * 481 * @since 1.0.0 482 */ build()483 public abstract ManagedChannel build(); 484 485 /** 486 * Returns the correctly typed version of the builder. 487 */ thisT()488 private T thisT() { 489 @SuppressWarnings("unchecked") 490 T thisT = (T) this; 491 return thisT; 492 } 493 } 494