blob: 87493d2ba0b8a904b3d105f5125c6e8aca3d0941 [file] [log] [blame]
Kun Zhangd3c5b002015-06-25 20:24:01 -07001/*
Carl Mastrangelo60a0b0c2018-05-03 14:55:21 -07002 * Copyright 2015 The gRPC Authors
Kun Zhangd3c5b002015-06-25 20:24:01 -07003 *
Carl Mastrangelo3bfd6302017-05-31 13:29:01 -07004 * 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
Carl Mastrangelo166108a2017-06-01 14:28:37 -07007 *
Carl Mastrangelo3bfd6302017-05-31 13:29:01 -07008 * http://www.apache.org/licenses/LICENSE-2.0
Carl Mastrangelo166108a2017-06-01 14:28:37 -07009 *
Carl Mastrangelo3bfd6302017-05-31 13:29:01 -070010 * 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.
Kun Zhangd3c5b002015-06-25 20:24:01 -070015 */
16
17package io.grpc;
18
Carl Mastrangelo8d49df22017-01-05 17:23:34 -080019import static com.google.common.base.Preconditions.checkArgument;
20
Kun Zhang38ba5862015-11-03 17:07:09 -080021import com.google.common.base.MoreObjects;
elandau053a18e2016-03-02 23:40:52 -080022import com.google.common.base.Preconditions;
Kun Zhang903197b2017-04-07 11:03:24 -070023import java.util.ArrayList;
elandau90323ad2016-06-02 09:14:48 -070024import java.util.Arrays;
Kun Zhang903197b2017-04-07 11:03:24 -070025import java.util.Collections;
26import java.util.List;
Eric Andersonf59e04f2015-08-04 12:27:36 -070027import java.util.concurrent.Executor;
Kun Zhangd3c5b002015-06-25 20:24:01 -070028import java.util.concurrent.TimeUnit;
Grant Oakley6bf8e0c2018-05-02 15:56:52 -070029import javax.annotation.CheckReturnValue;
Kun Zhangd3c5b002015-06-25 20:24:01 -070030import javax.annotation.Nullable;
31import javax.annotation.concurrent.Immutable;
32
33/**
34 * The collection of runtime options for a new RPC call.
35 *
36 * <p>A field that is not set is {@code null}.
37 */
38@Immutable
Grant Oakley6bf8e0c2018-05-02 15:56:52 -070039@CheckReturnValue
Kun Zhangd3c5b002015-06-25 20:24:01 -070040public final class CallOptions {
41 /**
42 * A blank {@code CallOptions} that all fields are not set.
43 */
Eric Andersondceb7642022-11-17 18:09:43 -080044 public static final CallOptions DEFAULT;
45
46 static {
47 Builder b = new Builder();
48 b.customOptions = new Object[0][2];
49 b.streamTracerFactories = Collections.emptyList();
50 DEFAULT = b.build();
51 }
Kun Zhangd3c5b002015-06-25 20:24:01 -070052
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -070053 @Nullable
pandaapo1b94f482022-11-18 05:11:27 +080054 private final Deadline deadline;
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -070055
Kun Zhang432cec72016-05-29 14:43:10 -070056 @Nullable
pandaapo1b94f482022-11-18 05:11:27 +080057 private final Executor executor;
Kun Zhang432cec72016-05-29 14:43:10 -070058
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -080059 @Nullable
pandaapo1b94f482022-11-18 05:11:27 +080060 private final String authority;
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +020061
pandaapo1b94f482022-11-18 05:11:27 +080062 @Nullable
63 private final CallCredentials credentials;
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -080064
pandaapo1b94f482022-11-18 05:11:27 +080065 @Nullable
66 private final String compressorName;
67
68 private final Object[][] customOptions;
69
70 private final List<ClientStreamTracer.Factory> streamTracerFactories;
Kun Zhang903197b2017-04-07 11:03:24 -070071
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -070072 /**
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -070073 * Opposite to fail fast.
74 */
Carl Mastrangelo53a3f122019-04-25 10:56:40 -070075 @Nullable
pandaapo1b94f482022-11-18 05:11:27 +080076 private final Boolean waitForReady;
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -070077
Carl Mastrangelo8d49df22017-01-05 17:23:34 -080078 @Nullable
pandaapo1b94f482022-11-18 05:11:27 +080079 private final Integer maxInboundMessageSize;
Carl Mastrangelo8d49df22017-01-05 17:23:34 -080080 @Nullable
pandaapo1b94f482022-11-18 05:11:27 +080081 private final Integer maxOutboundMessageSize;
Carl Mastrangelo8d49df22017-01-05 17:23:34 -080082
pandaapo1b94f482022-11-18 05:11:27 +080083 private CallOptions(Builder builder) {
84 this.deadline = builder.deadline;
85 this.executor = builder.executor;
86 this.authority = builder.authority;
87 this.credentials = builder.credentials;
88 this.compressorName = builder.compressorName;
89 this.customOptions = builder.customOptions;
90 this.streamTracerFactories = builder.streamTracerFactories;
91 this.waitForReady = builder.waitForReady;
92 this.maxInboundMessageSize = builder.maxInboundMessageSize;
93 this.maxOutboundMessageSize = builder.maxOutboundMessageSize;
94 }
95
96 static class Builder {
97 Deadline deadline;
98 Executor executor;
99 String authority;
100 CallCredentials credentials;
101 String compressorName;
Eric Andersondceb7642022-11-17 18:09:43 -0800102 Object[][] customOptions;
pandaapo1b94f482022-11-18 05:11:27 +0800103 // Unmodifiable list
Eric Andersondceb7642022-11-17 18:09:43 -0800104 List<ClientStreamTracer.Factory> streamTracerFactories;
pandaapo1b94f482022-11-18 05:11:27 +0800105 Boolean waitForReady;
106 Integer maxInboundMessageSize;
107 Integer maxOutboundMessageSize;
108
109 private CallOptions build() {
110 return new CallOptions(this);
111 }
112 }
Carl Mastrangelo8d49df22017-01-05 17:23:34 -0800113
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700114 /**
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -0700115 * Override the HTTP/2 authority the channel claims to be connecting to. <em>This is not
116 * generally safe.</em> Overriding allows advanced users to re-use a single Channel for multiple
117 * services, even if those services are hosted on different domain names. That assumes the
118 * server is virtually hosting multiple domains and is guaranteed to continue doing so. It is
119 * rare for a service provider to make such a guarantee. <em>At this time, there is no security
120 * verification of the overridden value, such as making sure the authority matches the server's
121 * TLS certificate.</em>
122 */
Carl Mastrangelo0f9e3fa2016-05-03 13:03:05 -0700123 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1767")
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -0700124 public CallOptions withAuthority(@Nullable String authority) {
pandaapo1b94f482022-11-18 05:11:27 +0800125 Builder builder = toBuilder(this);
126 builder.authority = authority;
127 return builder.build();
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -0700128 }
129
Kun Zhangd3c5b002015-06-25 20:24:01 -0700130 /**
Kun Zhang432cec72016-05-29 14:43:10 -0700131 * Returns a new {@code CallOptions} with the given call credentials.
132 */
Eric Anderson32fd3292016-06-30 16:58:34 -0700133 public CallOptions withCallCredentials(@Nullable CallCredentials credentials) {
pandaapo1b94f482022-11-18 05:11:27 +0800134 Builder builder = toBuilder(this);
135 builder.credentials = credentials;
136 return builder.build();
Kun Zhang432cec72016-05-29 14:43:10 -0700137 }
138
139 /**
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -0800140 * Sets the compression to use for the call. The compressor must be a valid name known in the
Larry Safran136665f2023-03-09 20:25:43 +0000141 * {@link CompressorRegistry}. By default, the "gzip" compressor will be available.
Eric Anderson57e94d12019-03-11 11:32:34 -0700142 *
143 * <p>It is only safe to call this if the server supports the compression format chosen. There is
144 * no negotiation performed; if the server does not support the compression chosen, the call will
145 * fail.
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -0800146 */
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -0800147 public CallOptions withCompression(@Nullable String compressorName) {
pandaapo1b94f482022-11-18 05:11:27 +0800148 Builder builder = toBuilder(this);
149 builder.compressorName = compressorName;
150 return builder.build();
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -0800151 }
152
153 /**
buchgr32ddf9f2016-03-24 13:23:50 +0100154 * Returns a new {@code CallOptions} with the given absolute deadline.
155 *
156 * <p>This is mostly used for propagating an existing deadline. {@link #withDeadlineAfter} is the
157 * recommended way of setting a new deadline,
158 *
159 * @param deadline the deadline or {@code null} for unsetting the deadline.
160 */
buchgr32ddf9f2016-03-24 13:23:50 +0100161 public CallOptions withDeadline(@Nullable Deadline deadline) {
pandaapo1b94f482022-11-18 05:11:27 +0800162 Builder builder = toBuilder(this);
163 builder.deadline = deadline;
164 return builder.build();
buchgr32ddf9f2016-03-24 13:23:50 +0100165 }
166
167 /**
Kun Zhangd3c5b002015-06-25 20:24:01 -0700168 * Returns a new {@code CallOptions} with a deadline that is after the given {@code duration} from
169 * now.
170 */
171 public CallOptions withDeadlineAfter(long duration, TimeUnit unit) {
buchgr32ddf9f2016-03-24 13:23:50 +0100172 return withDeadline(Deadline.after(duration, unit));
Kun Zhangd3c5b002015-06-25 20:24:01 -0700173 }
174
175 /**
buchgr32ddf9f2016-03-24 13:23:50 +0100176 * Returns the deadline or {@code null} if the deadline is not set.
177 */
buchgr32ddf9f2016-03-24 13:23:50 +0100178 @Nullable
179 public Deadline getDeadline() {
180 return deadline;
Kun Zhangd3c5b002015-06-25 20:24:01 -0700181 }
182
Carl Mastrangelo77b00e02015-08-11 11:28:55 -0700183 /**
zpencer347eb092017-05-17 17:12:45 -0700184 * Enables <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">
Eric Anderson4674b272020-04-30 15:30:24 -0700185 * 'wait for ready'</a> for the call. Wait-for-ready queues the RPC until a connection is
186 * available. This may dramatically increase the latency of the RPC, but avoids failing
187 * "unnecessarily." The default queues the RPC until an attempt to connect has completed, but
188 * fails RPCs without sending them if unable to connect.
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700189 */
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700190 public CallOptions withWaitForReady() {
pandaapo1b94f482022-11-18 05:11:27 +0800191 Builder builder = toBuilder(this);
192 builder.waitForReady = Boolean.TRUE;
193 return builder.build();
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700194 }
195
196 /**
197 * Disables 'wait for ready' feature for the call.
198 * This method should be rarely used because the default is without 'wait for ready'.
199 */
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700200 public CallOptions withoutWaitForReady() {
pandaapo1b94f482022-11-18 05:11:27 +0800201 Builder builder = toBuilder(this);
202 builder.waitForReady = Boolean.FALSE;
203 return builder.build();
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700204 }
205
206 /**
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -0800207 * Returns the compressor's name.
208 */
Carl Mastrangeloa3c79e82016-01-27 16:49:41 -0800209 @Nullable
210 public String getCompressor() {
211 return compressorName;
212 }
213
Kun Zhang942f4c92015-09-04 17:21:44 -0700214 /**
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -0700215 * Override the HTTP/2 authority the channel claims to be connecting to. <em>This is not
216 * generally safe.</em> Overriding allows advanced users to re-use a single Channel for multiple
217 * services, even if those services are hosted on different domain names. That assumes the
218 * server is virtually hosting multiple domains and is guaranteed to continue doing so. It is
219 * rare for a service provider to make such a guarantee. <em>At this time, there is no security
220 * verification of the overridden value, such as making sure the authority matches the server's
221 * TLS certificate.</em>
222 */
223 @Nullable
Carl Mastrangelo0f9e3fa2016-05-03 13:03:05 -0700224 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1767")
Carl Mastrangeloa508c1d2015-08-17 11:06:57 -0700225 public String getAuthority() {
226 return authority;
227 }
228
Eric Andersonf59e04f2015-08-04 12:27:36 -0700229 /**
Kun Zhang432cec72016-05-29 14:43:10 -0700230 * Returns the call credentials.
231 */
Kun Zhang432cec72016-05-29 14:43:10 -0700232 @Nullable
233 public CallCredentials getCredentials() {
234 return credentials;
235 }
236
237 /**
Eric Andersonf59e04f2015-08-04 12:27:36 -0700238 * Returns a new {@code CallOptions} with {@code executor} to be used instead of the default
239 * executor specified with {@link ManagedChannelBuilder#executor}.
240 */
David Hoover87cf4042018-12-19 15:47:54 -0800241 public CallOptions withExecutor(@Nullable Executor executor) {
pandaapo1b94f482022-11-18 05:11:27 +0800242 Builder builder = toBuilder(this);
243 builder.executor = executor;
244 return builder.build();
Eric Andersonf59e04f2015-08-04 12:27:36 -0700245 }
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200246
Kun Zhang903197b2017-04-07 11:03:24 -0700247 /**
248 * Returns a new {@code CallOptions} with a {@code ClientStreamTracerFactory} in addition to
249 * the existing factories.
250 *
251 * <p>This method doesn't replace existing factories, or try to de-duplicate factories.
252 */
253 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
254 public CallOptions withStreamTracerFactory(ClientStreamTracer.Factory factory) {
Kun Zhang903197b2017-04-07 11:03:24 -0700255 ArrayList<ClientStreamTracer.Factory> newList =
Carl Mastrangelo3a39b812019-02-04 10:03:50 -0800256 new ArrayList<>(streamTracerFactories.size() + 1);
Kun Zhang903197b2017-04-07 11:03:24 -0700257 newList.addAll(streamTracerFactories);
258 newList.add(factory);
pandaapo1b94f482022-11-18 05:11:27 +0800259 Builder builder = toBuilder(this);
260 builder.streamTracerFactories = Collections.unmodifiableList(newList);
261 return builder.build();
Kun Zhang903197b2017-04-07 11:03:24 -0700262 }
263
264 /**
265 * Returns an immutable list of {@code ClientStreamTracerFactory}s.
266 */
267 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
268 public List<ClientStreamTracer.Factory> getStreamTracerFactories() {
269 return streamTracerFactories;
270 }
271
Muxi Yanf6747762017-05-04 10:57:49 -0700272 /**
273 * Key for a key-value pair. Uses reference equality.
274 */
elandau90323ad2016-06-02 09:14:48 -0700275 public static final class Key<T> {
zpencer04a90bc2018-05-15 10:03:46 -0700276 private final String debugString;
elandau90323ad2016-06-02 09:14:48 -0700277 private final T defaultValue;
278
zpencer04a90bc2018-05-15 10:03:46 -0700279 private Key(String debugString, T defaultValue) {
280 this.debugString = debugString;
elandau90323ad2016-06-02 09:14:48 -0700281 this.defaultValue = defaultValue;
282 }
283
zpencer347eb092017-05-17 17:12:45 -0700284 /**
285 * Returns the user supplied default value for this key.
286 */
elandau90323ad2016-06-02 09:14:48 -0700287 public T getDefault() {
288 return defaultValue;
289 }
290
291 @Override
292 public String toString() {
zpencer04a90bc2018-05-15 10:03:46 -0700293 return debugString;
elandau90323ad2016-06-02 09:14:48 -0700294 }
295
296 /**
297 * Factory method for creating instances of {@link Key}.
298 *
zpencer04a90bc2018-05-15 10:03:46 -0700299 * @param debugString a string used to describe this key, used for debugging.
elandau90323ad2016-06-02 09:14:48 -0700300 * @param defaultValue default value to return when value for key not set
301 * @param <T> Key type
302 * @return Key object
zpencere806e382018-05-15 15:56:42 -0700303 * @deprecated Use {@link #create} or {@link #createWithDefault} instead. This method will
304 * be removed.
elandau90323ad2016-06-02 09:14:48 -0700305 */
zpencere806e382018-05-15 15:56:42 -0700306 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1869")
zpencer04a90bc2018-05-15 10:03:46 -0700307 @Deprecated
308 public static <T> Key<T> of(String debugString, T defaultValue) {
309 Preconditions.checkNotNull(debugString, "debugString");
Carl Mastrangelo3a39b812019-02-04 10:03:50 -0800310 return new Key<>(debugString, defaultValue);
zpencer04a90bc2018-05-15 10:03:46 -0700311 }
312
313 /**
314 * Factory method for creating instances of {@link Key}. The default value of the
315 * key is {@code null}.
316 *
317 * @param debugString a debug string that describes this key.
318 * @param <T> Key type
319 * @return Key object
320 * @since 1.13.0
321 */
322 public static <T> Key<T> create(String debugString) {
323 Preconditions.checkNotNull(debugString, "debugString");
Carl Mastrangelo3a39b812019-02-04 10:03:50 -0800324 return new Key<>(debugString, /*defaultValue=*/ null);
zpencer04a90bc2018-05-15 10:03:46 -0700325 }
326
327 /**
328 * Factory method for creating instances of {@link Key}.
329 *
330 * @param debugString a debug string that describes this key.
331 * @param defaultValue default value to return when value for key not set
332 * @param <T> Key type
333 * @return Key object
334 * @since 1.13.0
335 */
336 public static <T> Key<T> createWithDefault(String debugString, T defaultValue) {
337 Preconditions.checkNotNull(debugString, "debugString");
Carl Mastrangelo3a39b812019-02-04 10:03:50 -0800338 return new Key<>(debugString, defaultValue);
elandau90323ad2016-06-02 09:14:48 -0700339 }
340 }
341
342 /**
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200343 * Sets a custom option. Any existing value for the key is overwritten.
344 *
elandau90323ad2016-06-02 09:14:48 -0700345 * @param key The option key
346 * @param value The option value.
zpencer04a90bc2018-05-15 10:03:46 -0700347 * @since 1.13.0
elandau90323ad2016-06-02 09:14:48 -0700348 */
elandau90323ad2016-06-02 09:14:48 -0700349 public <T> CallOptions withOption(Key<T> key, T value) {
Carl Mastrangelo12854772016-08-12 14:52:00 -0700350 Preconditions.checkNotNull(key, "key");
351 Preconditions.checkNotNull(value, "value");
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200352
pandaapo1b94f482022-11-18 05:11:27 +0800353 Builder builder = toBuilder(this);
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200354 int existingIdx = -1;
355 for (int i = 0; i < customOptions.length; i++) {
356 if (key.equals(customOptions[i][0])) {
357 existingIdx = i;
358 break;
359 }
elandau90323ad2016-06-02 09:14:48 -0700360 }
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200361
pandaapo1b94f482022-11-18 05:11:27 +0800362 builder.customOptions = new Object[customOptions.length + (existingIdx == -1 ? 1 : 0)][2];
363 System.arraycopy(customOptions, 0, builder.customOptions, 0, customOptions.length);
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200364
365 if (existingIdx == -1) {
366 // Add a new option
pandaapo1b94f482022-11-18 05:11:27 +0800367 builder.customOptions[customOptions.length] = new Object[] {key, value};
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200368 } else {
369 // Replace an existing option
pandaapo1b94f482022-11-18 05:11:27 +0800370 builder.customOptions[existingIdx] = new Object[] {key, value};
Jakob Buchgraber33cd6be2016-06-15 10:29:05 +0200371 }
372
pandaapo1b94f482022-11-18 05:11:27 +0800373 return builder.build();
elandau90323ad2016-06-02 09:14:48 -0700374 }
375
376 /**
377 * Get the value for a custom option or its inherent default.
378 * @param key Key identifying option
379 */
380 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1869")
381 @SuppressWarnings("unchecked")
382 public <T> T getOption(Key<T> key) {
Carl Mastrangelo12854772016-08-12 14:52:00 -0700383 Preconditions.checkNotNull(key, "key");
elandau90323ad2016-06-02 09:14:48 -0700384 for (int i = 0; i < customOptions.length; i++) {
385 if (key.equals(customOptions[i][0])) {
386 return (T) customOptions[i][1];
387 }
388 }
389 return key.defaultValue;
390 }
Eric Andersonf59e04f2015-08-04 12:27:36 -0700391
yifeizhuang7eeb4112022-02-11 15:07:09 -0800392 /**
393 * Returns the executor override to use for this specific call, or {@code null} if there is no
394 * override. The executor is only for servicing this one call, so is not safe to use after
395 * {@link ClientCall.Listener#onClose}.
396 */
Eric Andersonf59e04f2015-08-04 12:27:36 -0700397 @Nullable
398 public Executor getExecutor() {
399 return executor;
400 }
401
Kun Zhangd3c5b002015-06-25 20:24:01 -0700402 /**
zpencer347eb092017-05-17 17:12:45 -0700403 * Returns whether <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">
404 * 'wait for ready'</a> option is enabled for the call. 'Fail fast' is the default option for gRPC
405 * calls and 'wait for ready' is the opposite to it.
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700406 */
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700407 public boolean isWaitForReady() {
Carl Mastrangelo53a3f122019-04-25 10:56:40 -0700408 return Boolean.TRUE.equals(waitForReady);
409 }
410
411 Boolean getWaitForReady() {
ZHANG Dapeng9d4a43f2016-06-11 09:30:16 -0700412 return waitForReady;
413 }
414
415 /**
Carl Mastrangelo8d49df22017-01-05 17:23:34 -0800416 * Sets the maximum allowed message size acceptable from the remote peer. If unset, this will
417 * default to the value set on the {@link ManagedChannelBuilder#maxInboundMessageSize(int)}.
418 */
419 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563")
420 public CallOptions withMaxInboundMessageSize(int maxSize) {
421 checkArgument(maxSize >= 0, "invalid maxsize %s", maxSize);
pandaapo1b94f482022-11-18 05:11:27 +0800422 Builder builder = toBuilder(this);
423 builder.maxInboundMessageSize = maxSize;
424 return builder.build();
Carl Mastrangelo8d49df22017-01-05 17:23:34 -0800425 }
426
427 /**
428 * Sets the maximum allowed message size acceptable sent to the remote peer.
429 */
430 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563")
431 public CallOptions withMaxOutboundMessageSize(int maxSize) {
432 checkArgument(maxSize >= 0, "invalid maxsize %s", maxSize);
pandaapo1b94f482022-11-18 05:11:27 +0800433 Builder builder = toBuilder(this);
434 builder.maxOutboundMessageSize = maxSize;
435 return builder.build();
Carl Mastrangelo8d49df22017-01-05 17:23:34 -0800436 }
437
438 /**
439 * Gets the maximum allowed message size acceptable from the remote peer.
440 */
441 @Nullable
442 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563")
443 public Integer getMaxInboundMessageSize() {
444 return maxInboundMessageSize;
445 }
446
447 /**
448 * Gets the maximum allowed message size acceptable to send the remote peer.
449 */
450 @Nullable
451 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563")
452 public Integer getMaxOutboundMessageSize() {
453 return maxOutboundMessageSize;
454 }
455
456 /**
pandaapo1b94f482022-11-18 05:11:27 +0800457 * Copy CallOptions.
Kun Zhangd3c5b002015-06-25 20:24:01 -0700458 */
pandaapo1b94f482022-11-18 05:11:27 +0800459 private static Builder toBuilder(CallOptions other) {
460 Builder builder = new Builder();
461 builder.deadline = other.deadline;
462 builder.executor = other.executor;
463 builder.authority = other.authority;
464 builder.credentials = other.credentials;
465 builder.compressorName = other.compressorName;
466 builder.customOptions = other.customOptions;
467 builder.streamTracerFactories = other.streamTracerFactories;
468 builder.waitForReady = other.waitForReady;
469 builder.maxInboundMessageSize = other.maxInboundMessageSize;
470 builder.maxOutboundMessageSize = other.maxOutboundMessageSize;
471 return builder;
Kun Zhangd3c5b002015-06-25 20:24:01 -0700472 }
473
474 @Override
475 public String toString() {
Carl Mastrangelo8d49df22017-01-05 17:23:34 -0800476 return MoreObjects.toStringHelper(this)
477 .add("deadline", deadline)
478 .add("authority", authority)
479 .add("callCredentials", credentials)
Carl Mastrangelo8d49df22017-01-05 17:23:34 -0800480 .add("executor", executor != null ? executor.getClass() : null)
481 .add("compressorName", compressorName)
482 .add("customOptions", Arrays.deepToString(customOptions))
483 .add("waitForReady", isWaitForReady())
484 .add("maxInboundMessageSize", maxInboundMessageSize)
485 .add("maxOutboundMessageSize", maxOutboundMessageSize)
Kun Zhang903197b2017-04-07 11:03:24 -0700486 .add("streamTracerFactories", streamTracerFactories)
Carl Mastrangelo8d49df22017-01-05 17:23:34 -0800487 .toString();
Kun Zhangd3c5b002015-06-25 20:24:01 -0700488 }
489}