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 static com.google.common.base.Preconditions.checkNotNull; 20 21 import com.google.common.base.Preconditions; 22 import java.io.File; 23 import java.io.InputStream; 24 import java.util.List; 25 import java.util.concurrent.Executor; 26 import java.util.concurrent.TimeUnit; 27 import javax.annotation.Nullable; 28 29 /** 30 * A builder for {@link Server} instances. 31 * 32 * @param <T> The concrete type of this builder. 33 * @since 1.0.0 34 */ 35 public abstract class ServerBuilder<T extends ServerBuilder<T>> { 36 37 /** 38 * Static factory for creating a new ServerBuilder. 39 * 40 * @param port the port to listen on 41 * @since 1.0.0 42 */ forPort(int port)43 public static ServerBuilder<?> forPort(int port) { 44 return ServerProvider.provider().builderForPort(port); 45 } 46 47 /** 48 * Execute application code directly in the transport thread. 49 * 50 * <p>Depending on the underlying transport, using a direct executor may lead to substantial 51 * performance improvements. However, it also requires the application to not block under 52 * any circumstances. 53 * 54 * <p>Calling this method is semantically equivalent to calling {@link #executor(Executor)} and 55 * passing in a direct executor. However, this is the preferred way as it may allow the transport 56 * to perform special optimizations. 57 * 58 * @return this 59 * @since 1.0.0 60 */ directExecutor()61 public abstract T directExecutor(); 62 63 /** 64 * Provides a custom executor. 65 * 66 * <p>It's an optional parameter. If the user has not provided an executor when the server is 67 * built, the builder will use a static cached thread pool. 68 * 69 * <p>The server won't take ownership of the given executor. It's caller's responsibility to 70 * shut down the executor when it's desired. 71 * 72 * @return this 73 * @since 1.0.0 74 */ executor(@ullable Executor executor)75 public abstract T executor(@Nullable Executor executor); 76 77 78 /** 79 * Allows for defining a way to provide a custom executor to handle the server call. 80 * This executor is the result of calling 81 * {@link ServerCallExecutorSupplier#getExecutor(ServerCall, Metadata)} per RPC. 82 * 83 * <p>It's an optional parameter. If it is provided, the {@link #executor(Executor)} would still 84 * run necessary tasks before the {@link ServerCallExecutorSupplier} is ready to be called, then 85 * it switches over. But if calling {@link ServerCallExecutorSupplier} returns null, the server 86 * call is still handled by the default {@link #executor(Executor)} as a fallback. 87 * 88 * @param executorSupplier the server call executor provider 89 * @return this 90 * @since 1.39.0 91 * 92 * */ 93 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/8274") callExecutor(ServerCallExecutorSupplier executorSupplier)94 public T callExecutor(ServerCallExecutorSupplier executorSupplier) { 95 return thisT(); 96 } 97 98 /** 99 * Adds a service implementation to the handler registry. 100 * 101 * @param service ServerServiceDefinition object 102 * @return this 103 * @since 1.0.0 104 */ addService(ServerServiceDefinition service)105 public abstract T addService(ServerServiceDefinition service); 106 107 /** 108 * Adds a service implementation to the handler registry. 109 * 110 * @param bindableService BindableService object 111 * @return this 112 * @since 1.0.0 113 */ addService(BindableService bindableService)114 public abstract T addService(BindableService bindableService); 115 116 /** 117 * Adds a list of service implementations to the handler registry together. 118 * 119 * @param services the list of ServerServiceDefinition objects 120 * @return this 121 * @since 1.37.0 122 */ 123 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/7925") addServices(List<ServerServiceDefinition> services)124 public final T addServices(List<ServerServiceDefinition> services) { 125 checkNotNull(services, "services"); 126 for (ServerServiceDefinition service : services) { 127 addService(service); 128 } 129 return thisT(); 130 } 131 132 /** 133 * Adds a {@link ServerInterceptor} that is run for all services on the server. Interceptors 134 * added through this method always run before per-service interceptors added through {@link 135 * ServerInterceptors}. Interceptors run in the reverse order in which they are added, just as 136 * with consecutive calls to {@code ServerInterceptors.intercept()}. 137 * 138 * @param interceptor the all-service interceptor 139 * @return this 140 * @since 1.5.0 141 */ intercept(ServerInterceptor interceptor)142 public T intercept(ServerInterceptor interceptor) { 143 throw new UnsupportedOperationException(); 144 } 145 146 /** 147 * Adds a {@link ServerTransportFilter}. The order of filters being added is the order they will 148 * be executed. 149 * 150 * @return this 151 * @since 1.2.0 152 */ 153 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2132") addTransportFilter(ServerTransportFilter filter)154 public T addTransportFilter(ServerTransportFilter filter) { 155 throw new UnsupportedOperationException(); 156 } 157 158 /** 159 * Adds a {@link ServerStreamTracer.Factory} to measure server-side traffic. The order of 160 * factories being added is the order they will be executed. 161 * 162 * @return this 163 * @since 1.3.0 164 */ 165 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861") addStreamTracerFactory(ServerStreamTracer.Factory factory)166 public T addStreamTracerFactory(ServerStreamTracer.Factory factory) { 167 throw new UnsupportedOperationException(); 168 } 169 170 /** 171 * Sets a fallback handler registry that will be looked up in if a method is not found in the 172 * primary registry. The primary registry (configured via {@code addService()}) is faster but 173 * immutable. The fallback registry is more flexible and allows implementations to mutate over 174 * time and load services on-demand. 175 * 176 * @return this 177 * @since 1.0.0 178 */ fallbackHandlerRegistry(@ullable HandlerRegistry fallbackRegistry)179 public abstract T fallbackHandlerRegistry(@Nullable HandlerRegistry fallbackRegistry); 180 181 /** 182 * Makes the server use TLS. 183 * 184 * @param certChain file containing the full certificate chain 185 * @param privateKey file containing the private key 186 * 187 * @return this 188 * @throws UnsupportedOperationException if the server does not support TLS. 189 * @since 1.0.0 190 */ useTransportSecurity(File certChain, File privateKey)191 public abstract T useTransportSecurity(File certChain, File privateKey); 192 193 /** 194 * Makes the server use TLS. 195 * 196 * @param certChain InputStream containing the full certificate chain 197 * @param privateKey InputStream containing the private key 198 * 199 * @return this 200 * @throws UnsupportedOperationException if the server does not support TLS, or does not support 201 * reading these files from an InputStream. 202 * @since 1.12.0 203 */ useTransportSecurity(InputStream certChain, InputStream privateKey)204 public T useTransportSecurity(InputStream certChain, InputStream privateKey) { 205 throw new UnsupportedOperationException(); 206 } 207 208 209 /** 210 * Set the decompression registry for use in the channel. This is an advanced API call and 211 * shouldn't be used unless you are using custom message encoding. The default supported 212 * decompressors are in {@code DecompressorRegistry.getDefaultInstance}. 213 * 214 * @return this 215 * @since 1.0.0 216 */ 217 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") decompressorRegistry(@ullable DecompressorRegistry registry)218 public abstract T decompressorRegistry(@Nullable DecompressorRegistry registry); 219 220 /** 221 * Set the compression registry for use in the channel. This is an advanced API call and 222 * shouldn't be used unless you are using custom message encoding. The default supported 223 * compressors are in {@code CompressorRegistry.getDefaultInstance}. 224 * 225 * @return this 226 * @since 1.0.0 227 */ 228 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") compressorRegistry(@ullable CompressorRegistry registry)229 public abstract T compressorRegistry(@Nullable CompressorRegistry registry); 230 231 /** 232 * Sets the permitted time for new connections to complete negotiation handshakes before being 233 * killed. 234 * 235 * @return this 236 * @throws IllegalArgumentException if timeout is negative 237 * @throws UnsupportedOperationException if unsupported 238 * @since 1.8.0 239 */ 240 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/3706") handshakeTimeout(long timeout, TimeUnit unit)241 public T handshakeTimeout(long timeout, TimeUnit unit) { 242 throw new UnsupportedOperationException(); 243 } 244 245 /** 246 * Sets the time without read activity before sending a keepalive ping. An unreasonably small 247 * value might be increased, and {@code Long.MAX_VALUE} nano seconds or an unreasonably large 248 * value will disable keepalive. The typical default is two hours when supported. 249 * 250 * @throws IllegalArgumentException if time is not positive 251 * @throws UnsupportedOperationException if unsupported 252 * @since 1.47.0 253 */ 254 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/9009") keepAliveTime(long keepAliveTime, TimeUnit timeUnit)255 public T keepAliveTime(long keepAliveTime, TimeUnit timeUnit) { 256 throw new UnsupportedOperationException(); 257 } 258 259 /** 260 * Sets a time waiting for read activity after sending a keepalive ping. If the time expires 261 * without any read activity on the connection, the connection is considered dead. An unreasonably 262 * small value might be increased. Defaults to 20 seconds when supported. 263 * 264 * <p>This value should be at least multiple times the RTT to allow for lost packets. 265 * 266 * @throws IllegalArgumentException if timeout is not positive 267 * @throws UnsupportedOperationException if unsupported 268 * @since 1.47.0 269 */ 270 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/9009") keepAliveTimeout(long keepAliveTimeout, TimeUnit timeUnit)271 public T keepAliveTimeout(long keepAliveTimeout, TimeUnit timeUnit) { 272 throw new UnsupportedOperationException(); 273 } 274 275 /** 276 * Sets the maximum connection idle time, connections being idle for longer than which will be 277 * gracefully terminated. Idleness duration is defined since the most recent time the number of 278 * outstanding RPCs became zero or the connection establishment. An unreasonably small value might 279 * be increased. {@code Long.MAX_VALUE} nano seconds or an unreasonably large value will disable 280 * max connection idle. 281 * 282 * @throws IllegalArgumentException if idle is not positive 283 * @throws UnsupportedOperationException if unsupported 284 * @since 1.47.0 285 */ 286 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/9009") maxConnectionIdle(long maxConnectionIdle, TimeUnit timeUnit)287 public T maxConnectionIdle(long maxConnectionIdle, TimeUnit timeUnit) { 288 throw new UnsupportedOperationException(); 289 } 290 291 /** 292 * Sets the maximum connection age, connections lasting longer than which will be gracefully 293 * terminated. An unreasonably small value might be increased. A random jitter of +/-10% will be 294 * added to it. {@code Long.MAX_VALUE} nano seconds or an unreasonably large value will disable 295 * max connection age. 296 * 297 * @throws IllegalArgumentException if age is not positive 298 * @throws UnsupportedOperationException if unsupported 299 * @since 1.47.0 300 */ 301 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/9009") maxConnectionAge(long maxConnectionAge, TimeUnit timeUnit)302 public T maxConnectionAge(long maxConnectionAge, TimeUnit timeUnit) { 303 throw new UnsupportedOperationException(); 304 } 305 306 /** 307 * Sets the grace time for the graceful connection termination. Once the max connection age 308 * is reached, RPCs have the grace time to complete. RPCs that do not complete in time will be 309 * cancelled, allowing the connection to terminate. {@code Long.MAX_VALUE} nano seconds or an 310 * unreasonably large value are considered infinite. 311 * 312 * @throws IllegalArgumentException if grace is negative 313 * @throws UnsupportedOperationException if unsupported 314 * @see #maxConnectionAge(long, TimeUnit) 315 * @since 1.47.0 316 */ 317 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/9009") maxConnectionAgeGrace(long maxConnectionAgeGrace, TimeUnit timeUnit)318 public T maxConnectionAgeGrace(long maxConnectionAgeGrace, TimeUnit timeUnit) { 319 throw new UnsupportedOperationException(); 320 } 321 322 /** 323 * Specify the most aggressive keep-alive time clients are permitted to configure. The server will 324 * try to detect clients exceeding this rate and when detected will forcefully close the 325 * connection. The typical default is 5 minutes when supported. 326 * 327 * <p>Even though a default is defined that allows some keep-alives, clients must not use 328 * keep-alive without approval from the service owner. Otherwise, they may experience failures in 329 * the future if the service becomes more restrictive. When unthrottled, keep-alives can cause a 330 * significant amount of traffic and CPU usage, so clients and servers should be conservative in 331 * what they use and accept. 332 * 333 * @throws IllegalArgumentException if time is negative 334 * @throws UnsupportedOperationException if unsupported 335 * @see #permitKeepAliveWithoutCalls(boolean) 336 * @since 1.47.0 337 */ 338 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/9009") permitKeepAliveTime(long keepAliveTime, TimeUnit timeUnit)339 public T permitKeepAliveTime(long keepAliveTime, TimeUnit timeUnit) { 340 throw new UnsupportedOperationException(); 341 } 342 343 /** 344 * Sets whether to allow clients to send keep-alive HTTP/2 PINGs even if there are no outstanding 345 * RPCs on the connection. Defaults to {@code false} when supported. 346 * 347 * @throws UnsupportedOperationException if unsupported 348 * @see #permitKeepAliveTime(long, TimeUnit) 349 * @since 1.47.0 350 */ 351 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/9009") permitKeepAliveWithoutCalls(boolean permit)352 public T permitKeepAliveWithoutCalls(boolean permit) { 353 throw new UnsupportedOperationException(); 354 } 355 356 /** 357 * Sets the maximum message size allowed to be received on the server. If not called, 358 * defaults to 4 MiB. The default provides protection to servers who haven't considered the 359 * possibility of receiving large messages while trying to be large enough to not be hit in normal 360 * usage. 361 * 362 * <p>This method is advisory, and implementations may decide to not enforce this. Currently, 363 * the only known transport to not enforce this is {@code InProcessServer}. 364 * 365 * @param bytes the maximum number of bytes a single message can be. 366 * @return this 367 * @throws IllegalArgumentException if bytes is negative. 368 * @throws UnsupportedOperationException if unsupported. 369 * @since 1.13.0 370 */ maxInboundMessageSize(int bytes)371 public T maxInboundMessageSize(int bytes) { 372 // intentional noop rather than throw, this method is only advisory. 373 Preconditions.checkArgument(bytes >= 0, "bytes must be >= 0"); 374 return thisT(); 375 } 376 377 /** 378 * Sets the maximum size of metadata allowed to be received. {@code Integer.MAX_VALUE} disables 379 * the enforcement. The default is implementation-dependent, but is not generally less than 8 KiB 380 * and may be unlimited. 381 * 382 * <p>This is cumulative size of the metadata. The precise calculation is 383 * implementation-dependent, but implementations are encouraged to follow the calculation used for 384 * <a href="http://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2"> 385 * HTTP/2's SETTINGS_MAX_HEADER_LIST_SIZE</a>. It sums the bytes from each entry's key and value, 386 * plus 32 bytes of overhead per entry. 387 * 388 * @param bytes the maximum size of received metadata 389 * @return this 390 * @throws IllegalArgumentException if bytes is non-positive 391 * @since 1.17.0 392 */ maxInboundMetadataSize(int bytes)393 public T maxInboundMetadataSize(int bytes) { 394 Preconditions.checkArgument(bytes > 0, "maxInboundMetadataSize must be > 0"); 395 // intentional noop rather than throw, this method is only advisory. 396 return thisT(); 397 } 398 399 /** 400 * Sets the BinaryLog object that this server should log to. The server does not take 401 * ownership of the object, and users are responsible for calling {@link BinaryLog#close()}. 402 * 403 * @param binaryLog the object to provide logging. 404 * @return this 405 * @since 1.13.0 406 */ 407 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4017") setBinaryLog(BinaryLog binaryLog)408 public T setBinaryLog(BinaryLog binaryLog) { 409 throw new UnsupportedOperationException(); 410 } 411 412 /** 413 * Builds a server using the given parameters. 414 * 415 * <p>The returned service will not been started or be bound a port. You will need to start it 416 * with {@link Server#start()}. 417 * 418 * @return a new Server 419 * @since 1.0.0 420 */ build()421 public abstract Server build(); 422 423 /** 424 * Returns the correctly typed version of the builder. 425 */ thisT()426 private T thisT() { 427 @SuppressWarnings("unchecked") 428 T thisT = (T) this; 429 return thisT; 430 } 431 } 432