All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.ratis.thirdparty.io.grpc.CallOptions Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
/*
 * Copyright 2015 The gRPC Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ratis.thirdparty.io.grpc;

import static org.apache.ratis.thirdparty.com.google.common.base.Preconditions.checkArgument;

import org.apache.ratis.thirdparty.com.google.common.base.MoreObjects;
import org.apache.ratis.thirdparty.com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

/**
 * The collection of runtime options for a new RPC call.
 *
 * 

A field that is not set is {@code null}. */ @Immutable @CheckReturnValue public final class CallOptions { /** * A blank {@code CallOptions} that all fields are not set. */ public static final CallOptions DEFAULT = new CallOptions(); // Although {@code CallOptions} is immutable, its fields are not final, so that we can initialize // them outside of constructor. Otherwise the constructor will have a potentially long list of // unnamed arguments, which is undesirable. @Nullable private Deadline deadline; @Nullable private Executor executor; @Nullable private String authority; @Nullable private CallCredentials credentials; @Nullable private String compressorName; private Object[][] customOptions; // Unmodifiable list private List streamTracerFactories = Collections.emptyList(); /** * Opposite to fail fast. */ @Nullable private Boolean waitForReady; @Nullable private Integer maxInboundMessageSize; @Nullable private Integer maxOutboundMessageSize; /** * Override the HTTP/2 authority the channel claims to be connecting to. This is not * generally safe. Overriding allows advanced users to re-use a single Channel for multiple * services, even if those services are hosted on different domain names. That assumes the * server is virtually hosting multiple domains and is guaranteed to continue doing so. It is * rare for a service provider to make such a guarantee. At this time, there is no security * verification of the overridden value, such as making sure the authority matches the server's * TLS certificate. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1767") public CallOptions withAuthority(@Nullable String authority) { CallOptions newOptions = new CallOptions(this); newOptions.authority = authority; return newOptions; } /** * Returns a new {@code CallOptions} with the given call credentials. */ public CallOptions withCallCredentials(@Nullable CallCredentials credentials) { CallOptions newOptions = new CallOptions(this); newOptions.credentials = credentials; return newOptions; } /** * Sets the compression to use for the call. The compressor must be a valid name known in the * {@link CompressorRegistry}. * *

It is only safe to call this if the server supports the compression format chosen. There is * no negotiation performed; if the server does not support the compression chosen, the call will * fail. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") public CallOptions withCompression(@Nullable String compressorName) { CallOptions newOptions = new CallOptions(this); newOptions.compressorName = compressorName; return newOptions; } /** * Returns a new {@code CallOptions} with the given absolute deadline. * *

This is mostly used for propagating an existing deadline. {@link #withDeadlineAfter} is the * recommended way of setting a new deadline, * * @param deadline the deadline or {@code null} for unsetting the deadline. */ public CallOptions withDeadline(@Nullable Deadline deadline) { CallOptions newOptions = new CallOptions(this); newOptions.deadline = deadline; return newOptions; } /** * Returns a new {@code CallOptions} with a deadline that is after the given {@code duration} from * now. */ public CallOptions withDeadlineAfter(long duration, TimeUnit unit) { return withDeadline(Deadline.after(duration, unit)); } /** * Returns the deadline or {@code null} if the deadline is not set. */ @Nullable public Deadline getDeadline() { return deadline; } /** * Enables * 'wait for ready' for the call. Wait-for-ready queues the RPC until a connection is * available. This may dramatically increase the latency of the RPC, but avoids failing * "unnecessarily." The default queues the RPC until an attempt to connect has completed, but * fails RPCs without sending them if unable to connect. */ public CallOptions withWaitForReady() { CallOptions newOptions = new CallOptions(this); newOptions.waitForReady = Boolean.TRUE; return newOptions; } /** * Disables 'wait for ready' feature for the call. * This method should be rarely used because the default is without 'wait for ready'. */ public CallOptions withoutWaitForReady() { CallOptions newOptions = new CallOptions(this); newOptions.waitForReady = Boolean.FALSE; return newOptions; } /** * Returns the compressor's name. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") @Nullable public String getCompressor() { return compressorName; } /** * Override the HTTP/2 authority the channel claims to be connecting to. This is not * generally safe. Overriding allows advanced users to re-use a single Channel for multiple * services, even if those services are hosted on different domain names. That assumes the * server is virtually hosting multiple domains and is guaranteed to continue doing so. It is * rare for a service provider to make such a guarantee. At this time, there is no security * verification of the overridden value, such as making sure the authority matches the server's * TLS certificate. */ @Nullable @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1767") public String getAuthority() { return authority; } /** * Returns the call credentials. */ @Nullable public CallCredentials getCredentials() { return credentials; } /** * Returns a new {@code CallOptions} with {@code executor} to be used instead of the default * executor specified with {@link ManagedChannelBuilder#executor}. */ public CallOptions withExecutor(@Nullable Executor executor) { CallOptions newOptions = new CallOptions(this); newOptions.executor = executor; return newOptions; } /** * Returns a new {@code CallOptions} with a {@code ClientStreamTracerFactory} in addition to * the existing factories. * *

This method doesn't replace existing factories, or try to de-duplicate factories. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861") public CallOptions withStreamTracerFactory(ClientStreamTracer.Factory factory) { CallOptions newOptions = new CallOptions(this); ArrayList newList = new ArrayList<>(streamTracerFactories.size() + 1); newList.addAll(streamTracerFactories); newList.add(factory); newOptions.streamTracerFactories = Collections.unmodifiableList(newList); return newOptions; } /** * Returns an immutable list of {@code ClientStreamTracerFactory}s. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861") public List getStreamTracerFactories() { return streamTracerFactories; } /** * Key for a key-value pair. Uses reference equality. */ public static final class Key { private final String debugString; private final T defaultValue; private Key(String debugString, T defaultValue) { this.debugString = debugString; this.defaultValue = defaultValue; } /** * Returns the user supplied default value for this key. */ public T getDefault() { return defaultValue; } @Override public String toString() { return debugString; } /** * Factory method for creating instances of {@link Key}. * * @param debugString a string used to describe this key, used for debugging. * @param defaultValue default value to return when value for key not set * @param Key type * @return Key object * @deprecated Use {@link #create} or {@link #createWithDefault} instead. This method will * be removed. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1869") @Deprecated public static Key of(String debugString, T defaultValue) { Preconditions.checkNotNull(debugString, "debugString"); return new Key<>(debugString, defaultValue); } /** * Factory method for creating instances of {@link Key}. The default value of the * key is {@code null}. * * @param debugString a debug string that describes this key. * @param Key type * @return Key object * @since 1.13.0 */ public static Key create(String debugString) { Preconditions.checkNotNull(debugString, "debugString"); return new Key<>(debugString, /*defaultValue=*/ null); } /** * Factory method for creating instances of {@link Key}. * * @param debugString a debug string that describes this key. * @param defaultValue default value to return when value for key not set * @param Key type * @return Key object * @since 1.13.0 */ public static Key createWithDefault(String debugString, T defaultValue) { Preconditions.checkNotNull(debugString, "debugString"); return new Key<>(debugString, defaultValue); } } /** * Sets a custom option. Any existing value for the key is overwritten. * * @param key The option key * @param value The option value. * @since 1.13.0 */ public CallOptions withOption(Key key, T value) { Preconditions.checkNotNull(key, "key"); Preconditions.checkNotNull(value, "value"); CallOptions newOptions = new CallOptions(this); int existingIdx = -1; for (int i = 0; i < customOptions.length; i++) { if (key.equals(customOptions[i][0])) { existingIdx = i; break; } } newOptions.customOptions = new Object[customOptions.length + (existingIdx == -1 ? 1 : 0)][2]; System.arraycopy(customOptions, 0, newOptions.customOptions, 0, customOptions.length); if (existingIdx == -1) { // Add a new option newOptions.customOptions[customOptions.length] = new Object[] {key, value}; } else { // Replace an existing option newOptions.customOptions[existingIdx] = new Object[] {key, value}; } return newOptions; } /** * Get the value for a custom option or its inherent default. * @param key Key identifying option */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1869") @SuppressWarnings("unchecked") public T getOption(Key key) { Preconditions.checkNotNull(key, "key"); for (int i = 0; i < customOptions.length; i++) { if (key.equals(customOptions[i][0])) { return (T) customOptions[i][1]; } } return key.defaultValue; } /** * Returns the executor override to use for this specific call, or {@code null} if there is no * override. The executor is only for servicing this one call, so is not safe to use after * {@link ClientCall.Listener#onClose}. */ @Nullable public Executor getExecutor() { return executor; } private CallOptions() { customOptions = new Object[0][2]; } /** * Returns whether * 'wait for ready' option is enabled for the call. 'Fail fast' is the default option for gRPC * calls and 'wait for ready' is the opposite to it. */ public boolean isWaitForReady() { return Boolean.TRUE.equals(waitForReady); } Boolean getWaitForReady() { return waitForReady; } /** * Sets the maximum allowed message size acceptable from the remote peer. If unset, this will * default to the value set on the {@link ManagedChannelBuilder#maxInboundMessageSize(int)}. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563") public CallOptions withMaxInboundMessageSize(int maxSize) { checkArgument(maxSize >= 0, "invalid maxsize %s", maxSize); CallOptions newOptions = new CallOptions(this); newOptions.maxInboundMessageSize = maxSize; return newOptions; } /** * Sets the maximum allowed message size acceptable sent to the remote peer. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563") public CallOptions withMaxOutboundMessageSize(int maxSize) { checkArgument(maxSize >= 0, "invalid maxsize %s", maxSize); CallOptions newOptions = new CallOptions(this); newOptions.maxOutboundMessageSize = maxSize; return newOptions; } /** * Gets the maximum allowed message size acceptable from the remote peer. */ @Nullable @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563") public Integer getMaxInboundMessageSize() { return maxInboundMessageSize; } /** * Gets the maximum allowed message size acceptable to send the remote peer. */ @Nullable @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563") public Integer getMaxOutboundMessageSize() { return maxOutboundMessageSize; } /** * Copy constructor. */ private CallOptions(CallOptions other) { deadline = other.deadline; authority = other.authority; credentials = other.credentials; executor = other.executor; compressorName = other.compressorName; customOptions = other.customOptions; waitForReady = other.waitForReady; maxInboundMessageSize = other.maxInboundMessageSize; maxOutboundMessageSize = other.maxOutboundMessageSize; streamTracerFactories = other.streamTracerFactories; } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("deadline", deadline) .add("authority", authority) .add("callCredentials", credentials) .add("executor", executor != null ? executor.getClass() : null) .add("compressorName", compressorName) .add("customOptions", Arrays.deepToString(customOptions)) .add("waitForReady", isWaitForReady()) .add("maxInboundMessageSize", maxInboundMessageSize) .add("maxOutboundMessageSize", maxOutboundMessageSize) .add("streamTracerFactories", streamTracerFactories) .toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy