From 36777be1e56c594b69034c021e121c3ff6a599aa Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Mon, 26 Jul 2021 18:39:59 +0000 Subject: [PATCH 1/8] feat: add extra contexts to ApiCallContext --- .../google/api/gax/grpc/GrpcCallContext.java | 54 +++++++++++++- .../api/gax/grpc/GrpcCallContextTest.java | 42 +++++++++++ .../api/gax/httpjson/HttpJsonCallContext.java | 54 +++++++++++++- .../gax/httpjson/HttpJsonCallContextTest.java | 42 +++++++++++ .../google/api/gax/rpc/ApiCallContext.java | 43 +++++++++++ .../gax/rpc/internal/ApiCallContextUtil.java | 71 +++++++++++++++++++ .../api/gax/rpc/testing/FakeCallContext.java | 56 ++++++++++++++- 7 files changed, 358 insertions(+), 4 deletions(-) create mode 100644 gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java index fdcdd9588..f79405e70 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java @@ -34,6 +34,7 @@ import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; +import com.google.api.gax.rpc.internal.ApiCallContextUtil; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -43,7 +44,6 @@ import com.google.common.collect.ImmutableSet; import io.grpc.CallCredentials; import io.grpc.CallOptions; -import io.grpc.CallOptions.Key; import io.grpc.Channel; import io.grpc.Deadline; import io.grpc.Metadata; @@ -66,7 +66,7 @@ */ @BetaApi("Reference ApiCallContext instead - this class is likely to experience breaking changes") public final class GrpcCallContext implements ApiCallContext { - static final CallOptions.Key TRACER_KEY = Key.create("gax.tracer"); + static final CallOptions.Key TRACER_KEY = CallOptions.Key.create("gax.tracer"); private final Channel channel; private final CallOptions callOptions; @@ -77,6 +77,7 @@ public final class GrpcCallContext implements ApiCallContext { @Nullable private final RetrySettings retrySettings; @Nullable private final ImmutableSet retryableCodes; private final ImmutableMap> extraHeaders; + private final ImmutableMap extraContexts; /** Returns an empty instance with a null channel and default {@link CallOptions}. */ public static GrpcCallContext createDefault() { @@ -88,6 +89,7 @@ public static GrpcCallContext createDefault() { null, null, ImmutableMap.>of(), + ImmutableMap.of(), null, null); } @@ -102,6 +104,7 @@ public static GrpcCallContext of(Channel channel, CallOptions callOptions) { null, null, ImmutableMap.>of(), + ImmutableMap.of(), null, null); } @@ -114,6 +117,7 @@ private GrpcCallContext( @Nullable Duration streamIdleTimeout, @Nullable Integer channelAffinity, ImmutableMap> extraHeaders, + ImmutableMap extraContexts, @Nullable RetrySettings retrySettings, @Nullable Set retryableCodes) { this.channel = channel; @@ -123,6 +127,7 @@ private GrpcCallContext( this.streamIdleTimeout = streamIdleTimeout; this.channelAffinity = channelAffinity; this.extraHeaders = Preconditions.checkNotNull(extraHeaders); + this.extraContexts = Preconditions.checkNotNull(extraContexts); this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); } @@ -187,6 +192,7 @@ public GrpcCallContext withTimeout(@Nullable Duration timeout) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, + this.extraContexts, this.retrySettings, this.retryableCodes); } @@ -212,6 +218,7 @@ public GrpcCallContext withStreamWaitTimeout(@Nullable Duration streamWaitTimeou this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, + this.extraContexts, this.retrySettings, this.retryableCodes); } @@ -231,6 +238,7 @@ public GrpcCallContext withStreamIdleTimeout(@Nullable Duration streamIdleTimeou streamIdleTimeout, this.channelAffinity, this.extraHeaders, + this.extraContexts, this.retrySettings, this.retryableCodes); } @@ -245,6 +253,7 @@ public GrpcCallContext withChannelAffinity(@Nullable Integer affinity) { this.streamIdleTimeout, affinity, this.extraHeaders, + this.extraContexts, this.retrySettings, this.retryableCodes); } @@ -263,6 +272,7 @@ public GrpcCallContext withExtraHeaders(Map> extraHeaders) this.streamIdleTimeout, this.channelAffinity, newExtraHeaders, + this.extraContexts, this.retrySettings, this.retryableCodes); } @@ -282,6 +292,7 @@ public GrpcCallContext withRetrySettings(RetrySettings retrySettings) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, + this.extraContexts, retrySettings, this.retryableCodes); } @@ -301,6 +312,7 @@ public GrpcCallContext withRetryableCodes(Set retryableCodes) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, + this.extraContexts, this.retrySettings, retryableCodes); } @@ -370,6 +382,9 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(this.extraHeaders, grpcCallContext.extraHeaders); + ImmutableMap newExtraContexts = + ApiCallContextUtil.mergeExtraContexts(this.extraContexts, grpcCallContext.extraContexts); + CallOptions newCallOptions = grpcCallContext .callOptions @@ -388,6 +403,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { newStreamIdleTimeout, newChannelAffinity, newExtraHeaders, + newExtraContexts, newRetrySettings, newRetryableCodes); } @@ -448,6 +464,7 @@ public GrpcCallContext withChannel(Channel newChannel) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, + this.extraContexts, this.retrySettings, this.retryableCodes); } @@ -462,6 +479,7 @@ public GrpcCallContext withCallOptions(CallOptions newCallOptions) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, + this.extraContexts, this.retrySettings, this.retryableCodes); } @@ -491,6 +509,36 @@ public GrpcCallContext withTracer(@Nonnull ApiTracer tracer) { return withCallOptions(callOptions.withOption(TRACER_KEY, tracer)); } + /** {@inheritDoc} */ + @Override + public GrpcCallContext withExtraContext(Key key, T extraContext) { + Preconditions.checkNotNull(key); + + ImmutableMap newExtraContexts = + ApiCallContextUtil.addExtraContext(extraContexts, key, extraContext); + return new GrpcCallContext( + this.channel, + this.callOptions, + this.timeout, + this.streamWaitTimeout, + this.streamIdleTimeout, + this.channelAffinity, + this.extraHeaders, + newExtraContexts, + this.retrySettings, + this.retryableCodes); + } + + /** {@inheritDoc} */ + @Override + public T getExtraContext(Key key) { + Preconditions.checkNotNull(key); + if (extraContexts.containsKey(key)) { + return (T) extraContexts.get(key); + } + return key.getDefault(); + } + @Override public int hashCode() { return Objects.hash( @@ -501,6 +549,7 @@ public int hashCode() { streamIdleTimeout, channelAffinity, extraHeaders, + extraContexts, retrySettings, retryableCodes); } @@ -522,6 +571,7 @@ public boolean equals(Object o) { && Objects.equals(this.streamIdleTimeout, that.streamIdleTimeout) && Objects.equals(this.channelAffinity, that.channelAffinity) && Objects.equals(this.extraHeaders, that.extraHeaders) + && Objects.equals(this.extraContexts, that.extraContexts) && Objects.equals(this.retrySettings, that.retrySettings) && Objects.equals(this.retryableCodes, that.retryableCodes); } diff --git a/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java b/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java index 1b9b5c187..9d4e23550 100644 --- a/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java +++ b/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java @@ -354,6 +354,48 @@ public void testWithRetryableCodes() { assertNotNull(context.getRetryableCodes()); } + @Test + public void testWithExtraContext() { + GrpcCallContext emptyCallContext = GrpcCallContext.createDefault(); + ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); + ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); + String testContext1 = "test1"; + String testContext2 = "test2"; + String testContextOverwrite = "test1Overwrite"; + GrpcCallContext context = + emptyCallContext + .withExtraContext(contextKey1, testContext1) + .withExtraContext(contextKey2, testContext2); + assertEquals(testContext1, context.getExtraContext(contextKey1)); + assertEquals(testContext2, context.getExtraContext(contextKey2)); + GrpcCallContext newContext = context.withExtraContext(contextKey1, testContextOverwrite); + assertEquals(testContextOverwrite, newContext.getExtraContext(contextKey1)); + } + + @Test + public void testMergeExtraContext() { + GrpcCallContext emptyCallContext = GrpcCallContext.createDefault(); + ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); + ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); + ApiCallContext.Key contextKey3 = ApiCallContext.Key.create("testKey3"); + String testContext1 = "test1"; + String testContext2 = "test2"; + String testContext3 = "test3"; + String testContextOverwrite = "test1Overwrite"; + GrpcCallContext context1 = + emptyCallContext + .withExtraContext(contextKey1, testContext1) + .withExtraContext(contextKey2, testContext2); + GrpcCallContext context2 = + emptyCallContext + .withExtraContext(contextKey1, testContextOverwrite) + .withExtraContext(contextKey3, testContext3); + ApiCallContext mergedContext = context1.merge(context2); + assertEquals(testContextOverwrite, mergedContext.getExtraContext(contextKey1)); + assertEquals(testContext2, mergedContext.getExtraContext(contextKey2)); + assertEquals(testContext3, mergedContext.getExtraContext(contextKey3)); + } + private static Map> createTestExtraHeaders(String... keyValues) { Map> extraHeaders = new HashMap<>(); for (int i = 0; i < keyValues.length; i += 2) { diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java index 700716217..81fcfcd0d 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java @@ -34,6 +34,7 @@ import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; +import com.google.api.gax.rpc.internal.ApiCallContextUtil; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -65,6 +66,7 @@ public final class HttpJsonCallContext implements ApiCallContext { private final Instant deadline; private final Credentials credentials; private final ImmutableMap> extraHeaders; + private final ImmutableMap extraContexts; private final ApiTracer tracer; private final RetrySettings retrySettings; private final ImmutableSet retryableCodes; @@ -72,7 +74,15 @@ public final class HttpJsonCallContext implements ApiCallContext { /** Returns an empty instance. */ public static HttpJsonCallContext createDefault() { return new HttpJsonCallContext( - null, null, null, null, ImmutableMap.>of(), null, null, null); + null, + null, + null, + null, + ImmutableMap.>of(), + ImmutableMap.of(), + null, + null, + null); } private HttpJsonCallContext( @@ -81,6 +91,7 @@ private HttpJsonCallContext( Instant deadline, Credentials credentials, ImmutableMap> extraHeaders, + ImmutableMap extraContexts, ApiTracer tracer, RetrySettings defaultRetrySettings, Set defaultRetryableCodes) { @@ -89,6 +100,7 @@ private HttpJsonCallContext( this.deadline = deadline; this.credentials = credentials; this.extraHeaders = extraHeaders; + this.extraContexts = extraContexts; this.tracer = tracer; this.retrySettings = defaultRetrySettings; this.retryableCodes = @@ -152,6 +164,9 @@ public HttpJsonCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(extraHeaders, httpJsonCallContext.extraHeaders); + ImmutableMap newExtraContext = + ApiCallContextUtil.mergeExtraContexts(extraContexts, httpJsonCallContext.extraContexts); + ApiTracer newTracer = httpJsonCallContext.tracer; if (newTracer == null) { newTracer = this.tracer; @@ -173,6 +188,7 @@ public HttpJsonCallContext merge(ApiCallContext inputCallContext) { newDeadline, newCredentials, newExtraHeaders, + newExtraContext, newTracer, newRetrySettings, newRetryableCodes); @@ -186,6 +202,7 @@ public HttpJsonCallContext withCredentials(Credentials newCredentials) { this.deadline, newCredentials, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -220,6 +237,7 @@ public HttpJsonCallContext withTimeout(Duration timeout) { this.deadline, this.credentials, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -265,6 +283,7 @@ public ApiCallContext withExtraHeaders(Map> extraHeaders) { this.deadline, this.credentials, newExtraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -276,6 +295,32 @@ public Map> getExtraHeaders() { return extraHeaders; } + /** {@inheritDoc} */ + @Override + public ApiCallContext withExtraContext(Key key, T extraContext) { + ImmutableMap newExtraContexts = + ApiCallContextUtil.addExtraContext(extraContexts, key, extraContext); + return new HttpJsonCallContext( + this.channel, + this.timeout, + this.deadline, + this.credentials, + this.extraHeaders, + newExtraContexts, + this.tracer, + this.retrySettings, + this.retryableCodes); + } + + /** {@inheritDoc} */ + @Override + public T getExtraContext(Key key) { + if (extraContexts.containsKey(key)) { + return (T) extraContexts.get(key); + } + return key.getDefault(); + } + public HttpJsonChannel getChannel() { return channel; } @@ -301,6 +346,7 @@ public HttpJsonCallContext withRetrySettings(RetrySettings retrySettings) { this.deadline, this.credentials, this.extraHeaders, + this.extraContexts, this.tracer, retrySettings, this.retryableCodes); @@ -319,6 +365,7 @@ public HttpJsonCallContext withRetryableCodes(Set retryableCode this.deadline, this.credentials, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, retryableCodes); @@ -331,6 +378,7 @@ public HttpJsonCallContext withChannel(HttpJsonChannel newChannel) { this.deadline, this.credentials, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -343,6 +391,7 @@ public HttpJsonCallContext withDeadline(Instant newDeadline) { newDeadline, this.credentials, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -368,6 +417,7 @@ public HttpJsonCallContext withTracer(@Nonnull ApiTracer newTracer) { this.deadline, this.credentials, this.extraHeaders, + this.extraContexts, newTracer, this.retrySettings, this.retryableCodes); @@ -387,6 +437,7 @@ public boolean equals(Object o) { && Objects.equals(this.deadline, that.deadline) && Objects.equals(this.credentials, that.credentials) && Objects.equals(this.extraHeaders, that.extraHeaders) + && Objects.equals(this.extraContexts, that.extraContexts) && Objects.equals(this.tracer, that.tracer) && Objects.equals(this.retrySettings, that.retrySettings) && Objects.equals(this.retryableCodes, that.retryableCodes); @@ -400,6 +451,7 @@ public int hashCode() { deadline, credentials, extraHeaders, + extraContexts, tracer, retrySettings, retryableCodes); diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java index 245ace65c..dea746f2c 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java @@ -229,4 +229,46 @@ public void testWithExtraHeaders() { ApiCallContext context = emptyContext.withExtraHeaders(headers); assertEquals(headers, context.getExtraHeaders()); } + + @Test + public void testWithExtraContext() { + ApiCallContext emptyCallContext = HttpJsonCallContext.createDefault(); + ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); + ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); + String testContext1 = "test1"; + String testContext2 = "test2"; + String testContextOverwrite = "test1Overwrite"; + ApiCallContext context = + emptyCallContext + .withExtraContext(contextKey1, testContext1) + .withExtraContext(contextKey2, testContext2); + assertEquals(testContext1, context.getExtraContext(contextKey1)); + assertEquals(testContext2, context.getExtraContext(contextKey2)); + ApiCallContext newContext = context.withExtraContext(contextKey1, testContextOverwrite); + assertEquals(testContextOverwrite, newContext.getExtraContext(contextKey1)); + } + + @Test + public void testMergeExtraContext() { + ApiCallContext emptyCallContext = HttpJsonCallContext.createDefault(); + ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); + ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); + ApiCallContext.Key contextKey3 = ApiCallContext.Key.create("testKey3"); + String testContext1 = "test1"; + String testContext2 = "test2"; + String testContext3 = "test3"; + String testContextOverwrite = "test1Overwrite"; + ApiCallContext context1 = + emptyCallContext + .withExtraContext(contextKey1, testContext1) + .withExtraContext(contextKey2, testContext2); + ApiCallContext context2 = + emptyCallContext + .withExtraContext(contextKey1, testContextOverwrite) + .withExtraContext(contextKey3, testContext3); + ApiCallContext mergedContext = context1.merge(context2); + assertEquals(testContextOverwrite, mergedContext.getExtraContext(contextKey1)); + assertEquals(testContext2, mergedContext.getExtraContext(contextKey2)); + assertEquals(testContext3, mergedContext.getExtraContext(contextKey3)); + } } diff --git a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java index a9366fbc5..02421142f 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java +++ b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java @@ -36,6 +36,7 @@ import com.google.api.gax.rpc.StatusCode.Code; import com.google.api.gax.tracing.ApiTracer; import com.google.auth.Credentials; +import com.google.common.base.Preconditions; import java.util.List; import java.util.Map; import java.util.Set; @@ -242,4 +243,46 @@ public interface ApiCallContext extends RetryingContext { /** Return the extra headers set for this context. */ @BetaApi("The surface for extra headers is not stable yet and may change in the future.") Map> getExtraHeaders(); + + /** + * Return a new ApiCallContext with the extra context merged into the present instance. Any + * existing value of the key is overwritten. + */ + @BetaApi("The surface for extra contexts is not stable yet and may change in the future.") + ApiCallContext withExtraContext(Key key, T extraContext); + + /** Return the extra context set for this context. */ + @SuppressWarnings("unchecked ") + @BetaApi("The surface for extra contexts is not stable yet and may change in the future.") + T getExtraContext(Key key); + + /** Key for extra contexts key-value pair. */ + public static final class Key { + private final String name; + private final T defaultValue; + + private Key(String name, T defaultValue) { + this.name = name; + this.defaultValue = defaultValue; + } + + /** + * Factory method for creating instances of {@link Key}. The default value of the key is null. + */ + public static Key create(String name) { + Preconditions.checkNotNull(name, "Key name cannot be null."); + return new Key<>(name, null); + } + + /** Factory method for creating instances of {@link Key} with default values. */ + public static Key createWithDefault(String name, T defaultValue) { + Preconditions.checkNotNull(name, "Key name cannot be null."); + return new Key<>(name, defaultValue); + } + + /** Returns the user supplied default value of the key. */ + public T getDefault() { + return defaultValue; + } + } } diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java new file mode 100644 index 000000000..853326e65 --- /dev/null +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java @@ -0,0 +1,71 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.rpc.internal; + +import com.google.api.core.InternalApi; +import com.google.api.gax.rpc.ApiCallContext.Key; +import com.google.common.collect.ImmutableMap; + +@InternalApi +public final class ApiCallContextUtil { + + public static ImmutableMap addExtraContext( + ImmutableMap oldExtraContexts, Key newKey, Object newContext) { + ImmutableMap.Builder builder = ImmutableMap.builder(); + if (!oldExtraContexts.containsKey(newKey)) { + builder.putAll(oldExtraContexts).put(newKey, newContext); + return builder.build(); + } + for (Key oldKey : oldExtraContexts.keySet()) { + if (oldKey.equals(newKey)) { + builder.put(oldKey, newContext); + } else { + builder.put(oldKey, oldExtraContexts.get(oldKey)); + } + } + return builder.build(); + } + + public static ImmutableMap mergeExtraContexts( + ImmutableMap oldExtraContexts, ImmutableMap newExtraContexts) { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (Key key : oldExtraContexts.keySet()) { + Object oldValue = oldExtraContexts.get(key); + Object newValue = newExtraContexts.get(key); + builder.put(key, newValue != null ? newValue : oldValue); + } + for (Key key : newExtraContexts.keySet()) { + if (!oldExtraContexts.containsKey(key)) { + builder.put(key, newExtraContexts.get(key)); + } + } + return builder.build(); + } +} diff --git a/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java b/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java index 6d16048d1..08fb27505 100644 --- a/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java +++ b/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java @@ -35,6 +35,7 @@ import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; +import com.google.api.gax.rpc.internal.ApiCallContextUtil; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -57,6 +58,7 @@ public class FakeCallContext implements ApiCallContext { private final Duration streamWaitTimeout; private final Duration streamIdleTimeout; private final ImmutableMap> extraHeaders; + private final ImmutableMap extraContexts; private final ApiTracer tracer; private final RetrySettings retrySettings; private final ImmutableSet retryableCodes; @@ -68,6 +70,7 @@ private FakeCallContext( Duration streamWaitTimeout, Duration streamIdleTimeout, ImmutableMap> extraHeaders, + ImmutableMap extraContexts, ApiTracer tracer, RetrySettings retrySettings, Set retryableCodes) { @@ -77,6 +80,7 @@ private FakeCallContext( this.streamWaitTimeout = streamWaitTimeout; this.streamIdleTimeout = streamIdleTimeout; this.extraHeaders = extraHeaders; + this.extraContexts = extraContexts; this.tracer = tracer; this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); @@ -84,7 +88,16 @@ private FakeCallContext( public static FakeCallContext createDefault() { return new FakeCallContext( - null, null, null, null, null, ImmutableMap.>of(), null, null, null); + null, + null, + null, + null, + null, + ImmutableMap.>of(), + ImmutableMap.of(), + null, + null, + null); } @Override @@ -157,6 +170,10 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(extraHeaders, fakeCallContext.extraHeaders); + + ImmutableMap newExtraContext = + ApiCallContextUtil.mergeExtraContexts(extraContexts, fakeCallContext.extraContexts); + return new FakeCallContext( newCallCredentials, newChannel, @@ -164,6 +181,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { newStreamWaitTimeout, newStreamIdleTimeout, newExtraHeaders, + newExtraContext, newTracer, newRetrySettings, newRetryableCodes); @@ -181,6 +199,7 @@ public FakeCallContext withRetrySettings(RetrySettings retrySettings) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, + this.extraContexts, this.tracer, retrySettings, this.retryableCodes); @@ -198,6 +217,7 @@ public FakeCallContext withRetryableCodes(Set retryableCodes) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, retryableCodes); @@ -237,6 +257,7 @@ public FakeCallContext withCredentials(Credentials credentials) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -261,6 +282,7 @@ public FakeCallContext withChannel(FakeChannel channel) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -285,6 +307,7 @@ public FakeCallContext withTimeout(Duration timeout) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -299,6 +322,7 @@ public ApiCallContext withStreamWaitTimeout(@Nullable Duration streamWaitTimeout streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -314,6 +338,7 @@ public ApiCallContext withStreamIdleTimeout(@Nullable Duration streamIdleTimeout this.streamWaitTimeout, streamIdleTimeout, this.extraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -331,6 +356,7 @@ public ApiCallContext withExtraHeaders(Map> extraHeaders) { streamWaitTimeout, streamIdleTimeout, newExtraHeaders, + this.extraContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -341,6 +367,33 @@ public Map> getExtraHeaders() { return this.extraHeaders; } + @Override + public ApiCallContext withExtraContext(Key key, T extraContext) { + Preconditions.checkNotNull(key); + ImmutableMap newExtraContexts = + ApiCallContextUtil.addExtraContext(extraContexts, key, extraContext); + return new FakeCallContext( + credentials, + channel, + timeout, + streamWaitTimeout, + streamIdleTimeout, + extraHeaders, + newExtraContexts, + tracer, + retrySettings, + retryableCodes); + } + + @Override + public T getExtraContext(Key key) { + Preconditions.checkNotNull(key); + if (extraContexts.containsKey(key)) { + return (T) extraContexts.get(key); + } + return key.getDefault(); + } + /** {@inheritDoc} */ @Override @Nonnull @@ -363,6 +416,7 @@ public ApiCallContext withTracer(@Nonnull ApiTracer tracer) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, + this.extraContexts, tracer, this.retrySettings, this.retryableCodes); From 26435ea73bc899097fe9e2b375fdafbcf6ec1437 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Wed, 28 Jul 2021 14:35:04 +0000 Subject: [PATCH 2/8] refactor --- .../google/api/gax/grpc/GrpcCallContext.java | 56 +++++----- .../api/gax/grpc/GrpcCallContextTest.java | 30 +++--- .../api/gax/httpjson/HttpJsonCallContext.java | 50 ++++----- .../gax/httpjson/HttpJsonCallContextTest.java | 30 +++--- .../google/api/gax/rpc/ApiCallContext.java | 18 ++-- .../gax/rpc/internal/ApiCallContextUtil.java | 71 ------------- .../rpc/internal/ApiCallCustomContexts.java | 100 ++++++++++++++++++ .../api/gax/rpc/testing/FakeCallContext.java | 47 ++++---- 8 files changed, 207 insertions(+), 195 deletions(-) delete mode 100644 gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java create mode 100644 gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java index f79405e70..81648795b 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java @@ -34,7 +34,7 @@ import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; -import com.google.api.gax.rpc.internal.ApiCallContextUtil; +import com.google.api.gax.rpc.internal.ApiCallCustomContexts; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -77,7 +77,7 @@ public final class GrpcCallContext implements ApiCallContext { @Nullable private final RetrySettings retrySettings; @Nullable private final ImmutableSet retryableCodes; private final ImmutableMap> extraHeaders; - private final ImmutableMap extraContexts; + private final ApiCallCustomContexts customContexts; /** Returns an empty instance with a null channel and default {@link CallOptions}. */ public static GrpcCallContext createDefault() { @@ -89,7 +89,7 @@ public static GrpcCallContext createDefault() { null, null, ImmutableMap.>of(), - ImmutableMap.of(), + ApiCallCustomContexts.createDefault(), null, null); } @@ -104,7 +104,7 @@ public static GrpcCallContext of(Channel channel, CallOptions callOptions) { null, null, ImmutableMap.>of(), - ImmutableMap.of(), + ApiCallCustomContexts.createDefault(), null, null); } @@ -117,7 +117,7 @@ private GrpcCallContext( @Nullable Duration streamIdleTimeout, @Nullable Integer channelAffinity, ImmutableMap> extraHeaders, - ImmutableMap extraContexts, + ApiCallCustomContexts customContexts, @Nullable RetrySettings retrySettings, @Nullable Set retryableCodes) { this.channel = channel; @@ -127,7 +127,7 @@ private GrpcCallContext( this.streamIdleTimeout = streamIdleTimeout; this.channelAffinity = channelAffinity; this.extraHeaders = Preconditions.checkNotNull(extraHeaders); - this.extraContexts = Preconditions.checkNotNull(extraContexts); + this.customContexts = Preconditions.checkNotNull(customContexts); this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); } @@ -192,7 +192,7 @@ public GrpcCallContext withTimeout(@Nullable Duration timeout) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, this.retryableCodes); } @@ -218,7 +218,7 @@ public GrpcCallContext withStreamWaitTimeout(@Nullable Duration streamWaitTimeou this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, this.retryableCodes); } @@ -238,7 +238,7 @@ public GrpcCallContext withStreamIdleTimeout(@Nullable Duration streamIdleTimeou streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, this.retryableCodes); } @@ -253,7 +253,7 @@ public GrpcCallContext withChannelAffinity(@Nullable Integer affinity) { this.streamIdleTimeout, affinity, this.extraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, this.retryableCodes); } @@ -272,7 +272,7 @@ public GrpcCallContext withExtraHeaders(Map> extraHeaders) this.streamIdleTimeout, this.channelAffinity, newExtraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, this.retryableCodes); } @@ -292,7 +292,7 @@ public GrpcCallContext withRetrySettings(RetrySettings retrySettings) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.extraContexts, + this.customContexts, retrySettings, this.retryableCodes); } @@ -312,7 +312,7 @@ public GrpcCallContext withRetryableCodes(Set retryableCodes) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, retryableCodes); } @@ -382,8 +382,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(this.extraHeaders, grpcCallContext.extraHeaders); - ImmutableMap newExtraContexts = - ApiCallContextUtil.mergeExtraContexts(this.extraContexts, grpcCallContext.extraContexts); + ApiCallCustomContexts newCustomContexts = customContexts.merge(grpcCallContext.customContexts); CallOptions newCallOptions = grpcCallContext @@ -403,7 +402,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { newStreamIdleTimeout, newChannelAffinity, newExtraHeaders, - newExtraContexts, + newCustomContexts, newRetrySettings, newRetryableCodes); } @@ -464,7 +463,7 @@ public GrpcCallContext withChannel(Channel newChannel) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, this.retryableCodes); } @@ -479,7 +478,7 @@ public GrpcCallContext withCallOptions(CallOptions newCallOptions) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.extraContexts, + this.customContexts, this.retrySettings, this.retryableCodes); } @@ -511,11 +510,8 @@ public GrpcCallContext withTracer(@Nonnull ApiTracer tracer) { /** {@inheritDoc} */ @Override - public GrpcCallContext withExtraContext(Key key, T extraContext) { - Preconditions.checkNotNull(key); - - ImmutableMap newExtraContexts = - ApiCallContextUtil.addExtraContext(extraContexts, key, extraContext); + public GrpcCallContext withCustomContext(Key key, T value) { + ApiCallCustomContexts newCustomContexts = customContexts.withCustomContext(key, value); return new GrpcCallContext( this.channel, this.callOptions, @@ -524,19 +520,15 @@ public GrpcCallContext withExtraContext(Key key, T extraContext) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - newExtraContexts, + newCustomContexts, this.retrySettings, this.retryableCodes); } /** {@inheritDoc} */ @Override - public T getExtraContext(Key key) { - Preconditions.checkNotNull(key); - if (extraContexts.containsKey(key)) { - return (T) extraContexts.get(key); - } - return key.getDefault(); + public T getCustomContext(Key key) { + return customContexts.getCustomContext(key); } @Override @@ -549,7 +541,7 @@ public int hashCode() { streamIdleTimeout, channelAffinity, extraHeaders, - extraContexts, + customContexts, retrySettings, retryableCodes); } @@ -571,7 +563,7 @@ public boolean equals(Object o) { && Objects.equals(this.streamIdleTimeout, that.streamIdleTimeout) && Objects.equals(this.channelAffinity, that.channelAffinity) && Objects.equals(this.extraHeaders, that.extraHeaders) - && Objects.equals(this.extraContexts, that.extraContexts) + && Objects.equals(this.customContexts, that.customContexts) && Objects.equals(this.retrySettings, that.retrySettings) && Objects.equals(this.retryableCodes, that.retryableCodes); } diff --git a/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java b/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java index 9d4e23550..f07731601 100644 --- a/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java +++ b/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java @@ -355,7 +355,7 @@ public void testWithRetryableCodes() { } @Test - public void testWithExtraContext() { + public void testWithCustomContexts() { GrpcCallContext emptyCallContext = GrpcCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -364,16 +364,16 @@ public void testWithExtraContext() { String testContextOverwrite = "test1Overwrite"; GrpcCallContext context = emptyCallContext - .withExtraContext(contextKey1, testContext1) - .withExtraContext(contextKey2, testContext2); - assertEquals(testContext1, context.getExtraContext(contextKey1)); - assertEquals(testContext2, context.getExtraContext(contextKey2)); - GrpcCallContext newContext = context.withExtraContext(contextKey1, testContextOverwrite); - assertEquals(testContextOverwrite, newContext.getExtraContext(contextKey1)); + .withCustomContext(contextKey1, testContext1) + .withCustomContext(contextKey2, testContext2); + assertEquals(testContext1, context.getCustomContext(contextKey1)); + assertEquals(testContext2, context.getCustomContext(contextKey2)); + GrpcCallContext newContext = context.withCustomContext(contextKey1, testContextOverwrite); + assertEquals(testContextOverwrite, newContext.getCustomContext(contextKey1)); } @Test - public void testMergeExtraContext() { + public void testMergeCustomContexts() { GrpcCallContext emptyCallContext = GrpcCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -384,16 +384,16 @@ public void testMergeExtraContext() { String testContextOverwrite = "test1Overwrite"; GrpcCallContext context1 = emptyCallContext - .withExtraContext(contextKey1, testContext1) - .withExtraContext(contextKey2, testContext2); + .withCustomContext(contextKey1, testContext1) + .withCustomContext(contextKey2, testContext2); GrpcCallContext context2 = emptyCallContext - .withExtraContext(contextKey1, testContextOverwrite) - .withExtraContext(contextKey3, testContext3); + .withCustomContext(contextKey1, testContextOverwrite) + .withCustomContext(contextKey3, testContext3); ApiCallContext mergedContext = context1.merge(context2); - assertEquals(testContextOverwrite, mergedContext.getExtraContext(contextKey1)); - assertEquals(testContext2, mergedContext.getExtraContext(contextKey2)); - assertEquals(testContext3, mergedContext.getExtraContext(contextKey3)); + assertEquals(testContextOverwrite, mergedContext.getCustomContext(contextKey1)); + assertEquals(testContext2, mergedContext.getCustomContext(contextKey2)); + assertEquals(testContext3, mergedContext.getCustomContext(contextKey3)); } private static Map> createTestExtraHeaders(String... keyValues) { diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java index 81fcfcd0d..84edbda79 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java @@ -34,7 +34,7 @@ import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; -import com.google.api.gax.rpc.internal.ApiCallContextUtil; +import com.google.api.gax.rpc.internal.ApiCallCustomContexts; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -66,7 +66,7 @@ public final class HttpJsonCallContext implements ApiCallContext { private final Instant deadline; private final Credentials credentials; private final ImmutableMap> extraHeaders; - private final ImmutableMap extraContexts; + private final ApiCallCustomContexts customContexts; private final ApiTracer tracer; private final RetrySettings retrySettings; private final ImmutableSet retryableCodes; @@ -79,7 +79,7 @@ public static HttpJsonCallContext createDefault() { null, null, ImmutableMap.>of(), - ImmutableMap.of(), + ApiCallCustomContexts.createDefault(), null, null, null); @@ -91,7 +91,7 @@ private HttpJsonCallContext( Instant deadline, Credentials credentials, ImmutableMap> extraHeaders, - ImmutableMap extraContexts, + ApiCallCustomContexts customContexts, ApiTracer tracer, RetrySettings defaultRetrySettings, Set defaultRetryableCodes) { @@ -100,7 +100,7 @@ private HttpJsonCallContext( this.deadline = deadline; this.credentials = credentials; this.extraHeaders = extraHeaders; - this.extraContexts = extraContexts; + this.customContexts = customContexts; this.tracer = tracer; this.retrySettings = defaultRetrySettings; this.retryableCodes = @@ -164,8 +164,8 @@ public HttpJsonCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(extraHeaders, httpJsonCallContext.extraHeaders); - ImmutableMap newExtraContext = - ApiCallContextUtil.mergeExtraContexts(extraContexts, httpJsonCallContext.extraContexts); + ApiCallCustomContexts newCustomContext = + customContexts.merge(httpJsonCallContext.customContexts); ApiTracer newTracer = httpJsonCallContext.tracer; if (newTracer == null) { @@ -188,7 +188,7 @@ public HttpJsonCallContext merge(ApiCallContext inputCallContext) { newDeadline, newCredentials, newExtraHeaders, - newExtraContext, + newCustomContext, newTracer, newRetrySettings, newRetryableCodes); @@ -202,7 +202,7 @@ public HttpJsonCallContext withCredentials(Credentials newCredentials) { this.deadline, newCredentials, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -237,7 +237,7 @@ public HttpJsonCallContext withTimeout(Duration timeout) { this.deadline, this.credentials, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -283,7 +283,7 @@ public ApiCallContext withExtraHeaders(Map> extraHeaders) { this.deadline, this.credentials, newExtraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -297,16 +297,15 @@ public Map> getExtraHeaders() { /** {@inheritDoc} */ @Override - public ApiCallContext withExtraContext(Key key, T extraContext) { - ImmutableMap newExtraContexts = - ApiCallContextUtil.addExtraContext(extraContexts, key, extraContext); + public ApiCallContext withCustomContext(Key key, T value) { + ApiCallCustomContexts newCustomContexts = customContexts.withCustomContext(key, value); return new HttpJsonCallContext( this.channel, this.timeout, this.deadline, this.credentials, this.extraHeaders, - newExtraContexts, + newCustomContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -314,11 +313,8 @@ public ApiCallContext withExtraContext(Key key, T extraContext) { /** {@inheritDoc} */ @Override - public T getExtraContext(Key key) { - if (extraContexts.containsKey(key)) { - return (T) extraContexts.get(key); - } - return key.getDefault(); + public T getCustomContext(Key key) { + return customContexts.getCustomContext(key); } public HttpJsonChannel getChannel() { @@ -346,7 +342,7 @@ public HttpJsonCallContext withRetrySettings(RetrySettings retrySettings) { this.deadline, this.credentials, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, retrySettings, this.retryableCodes); @@ -365,7 +361,7 @@ public HttpJsonCallContext withRetryableCodes(Set retryableCode this.deadline, this.credentials, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, retryableCodes); @@ -378,7 +374,7 @@ public HttpJsonCallContext withChannel(HttpJsonChannel newChannel) { this.deadline, this.credentials, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -391,7 +387,7 @@ public HttpJsonCallContext withDeadline(Instant newDeadline) { newDeadline, this.credentials, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -417,7 +413,7 @@ public HttpJsonCallContext withTracer(@Nonnull ApiTracer newTracer) { this.deadline, this.credentials, this.extraHeaders, - this.extraContexts, + this.customContexts, newTracer, this.retrySettings, this.retryableCodes); @@ -437,7 +433,7 @@ public boolean equals(Object o) { && Objects.equals(this.deadline, that.deadline) && Objects.equals(this.credentials, that.credentials) && Objects.equals(this.extraHeaders, that.extraHeaders) - && Objects.equals(this.extraContexts, that.extraContexts) + && Objects.equals(this.customContexts, that.customContexts) && Objects.equals(this.tracer, that.tracer) && Objects.equals(this.retrySettings, that.retrySettings) && Objects.equals(this.retryableCodes, that.retryableCodes); @@ -451,7 +447,7 @@ public int hashCode() { deadline, credentials, extraHeaders, - extraContexts, + customContexts, tracer, retrySettings, retryableCodes); diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java index dea746f2c..426aa9cc3 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java @@ -231,7 +231,7 @@ public void testWithExtraHeaders() { } @Test - public void testWithExtraContext() { + public void testWithCustomContexts() { ApiCallContext emptyCallContext = HttpJsonCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -240,16 +240,16 @@ public void testWithExtraContext() { String testContextOverwrite = "test1Overwrite"; ApiCallContext context = emptyCallContext - .withExtraContext(contextKey1, testContext1) - .withExtraContext(contextKey2, testContext2); - assertEquals(testContext1, context.getExtraContext(contextKey1)); - assertEquals(testContext2, context.getExtraContext(contextKey2)); - ApiCallContext newContext = context.withExtraContext(contextKey1, testContextOverwrite); - assertEquals(testContextOverwrite, newContext.getExtraContext(contextKey1)); + .withCustomContext(contextKey1, testContext1) + .withCustomContext(contextKey2, testContext2); + assertEquals(testContext1, context.getCustomContext(contextKey1)); + assertEquals(testContext2, context.getCustomContext(contextKey2)); + ApiCallContext newContext = context.withCustomContext(contextKey1, testContextOverwrite); + assertEquals(testContextOverwrite, newContext.getCustomContext(contextKey1)); } @Test - public void testMergeExtraContext() { + public void testMergeCustomContexts() { ApiCallContext emptyCallContext = HttpJsonCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -260,15 +260,15 @@ public void testMergeExtraContext() { String testContextOverwrite = "test1Overwrite"; ApiCallContext context1 = emptyCallContext - .withExtraContext(contextKey1, testContext1) - .withExtraContext(contextKey2, testContext2); + .withCustomContext(contextKey1, testContext1) + .withCustomContext(contextKey2, testContext2); ApiCallContext context2 = emptyCallContext - .withExtraContext(contextKey1, testContextOverwrite) - .withExtraContext(contextKey3, testContext3); + .withCustomContext(contextKey1, testContextOverwrite) + .withCustomContext(contextKey3, testContext3); ApiCallContext mergedContext = context1.merge(context2); - assertEquals(testContextOverwrite, mergedContext.getExtraContext(contextKey1)); - assertEquals(testContext2, mergedContext.getExtraContext(contextKey2)); - assertEquals(testContext3, mergedContext.getExtraContext(contextKey3)); + assertEquals(testContextOverwrite, mergedContext.getCustomContext(contextKey1)); + assertEquals(testContext2, mergedContext.getCustomContext(contextKey2)); + assertEquals(testContext3, mergedContext.getCustomContext(contextKey3)); } } diff --git a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java index 02421142f..5c7a07af2 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java +++ b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java @@ -245,19 +245,19 @@ public interface ApiCallContext extends RetryingContext { Map> getExtraHeaders(); /** - * Return a new ApiCallContext with the extra context merged into the present instance. Any + * Return a new ApiCallContext with the custom context merged into the present instance. Any * existing value of the key is overwritten. */ - @BetaApi("The surface for extra contexts is not stable yet and may change in the future.") - ApiCallContext withExtraContext(Key key, T extraContext); + @BetaApi("The surface for custom contexts is not stable yet and may change in the future.") + ApiCallContext withCustomContext(Key key, T value); - /** Return the extra context set for this context. */ - @SuppressWarnings("unchecked ") - @BetaApi("The surface for extra contexts is not stable yet and may change in the future.") - T getExtraContext(Key key); + /** Return the custom context set for this context. */ + @SuppressWarnings("unchecked") + @BetaApi("The surface for custom contexts is not stable yet and may change in the future.") + T getCustomContext(Key key); - /** Key for extra contexts key-value pair. */ - public static final class Key { + /** Key for custom contexts key-value pair. */ + final class Key { private final String name; private final T defaultValue; diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java deleted file mode 100644 index 853326e65..000000000 --- a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextUtil.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2021 Google LLC - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.google.api.gax.rpc.internal; - -import com.google.api.core.InternalApi; -import com.google.api.gax.rpc.ApiCallContext.Key; -import com.google.common.collect.ImmutableMap; - -@InternalApi -public final class ApiCallContextUtil { - - public static ImmutableMap addExtraContext( - ImmutableMap oldExtraContexts, Key newKey, Object newContext) { - ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!oldExtraContexts.containsKey(newKey)) { - builder.putAll(oldExtraContexts).put(newKey, newContext); - return builder.build(); - } - for (Key oldKey : oldExtraContexts.keySet()) { - if (oldKey.equals(newKey)) { - builder.put(oldKey, newContext); - } else { - builder.put(oldKey, oldExtraContexts.get(oldKey)); - } - } - return builder.build(); - } - - public static ImmutableMap mergeExtraContexts( - ImmutableMap oldExtraContexts, ImmutableMap newExtraContexts) { - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (Key key : oldExtraContexts.keySet()) { - Object oldValue = oldExtraContexts.get(key); - Object newValue = newExtraContexts.get(key); - builder.put(key, newValue != null ? newValue : oldValue); - } - for (Key key : newExtraContexts.keySet()) { - if (!oldExtraContexts.containsKey(key)) { - builder.put(key, newExtraContexts.get(key)); - } - } - return builder.build(); - } -} diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java new file mode 100644 index 000000000..002f96828 --- /dev/null +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java @@ -0,0 +1,100 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.rpc.internal; + +import com.google.api.core.InternalApi; +import com.google.api.gax.rpc.ApiCallContext; +import com.google.api.gax.rpc.ApiCallContext.Key; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; + +/** ApiCallCustomContexts encapsulates custom context data to pass in a {@link ApiCallContext} */ +@InternalApi +public final class ApiCallCustomContexts { + + private ImmutableMap customContexts; + + private ApiCallCustomContexts(ImmutableMap contexts) { + this.customContexts = Preconditions.checkNotNull(contexts); + } + + /** Create an empty custom call context. */ + public static ApiCallCustomContexts createDefault() { + return new ApiCallCustomContexts(ImmutableMap.of()); + } + + /** Add a context to custom contexts. Any existing value of the key is overwritten. */ + public ApiCallCustomContexts withCustomContext(Key key, T context) { + Preconditions.checkNotNull(key); + Preconditions.checkNotNull(context); + ImmutableMap.Builder builder = ImmutableMap.builder(); + if (!customContexts.containsKey(key)) { + builder.putAll(customContexts).put(key, context); + } else { + for (Key oldKey : customContexts.keySet()) { + if (oldKey.equals(key)) { + builder.put(oldKey, context); + } else { + builder.put(oldKey, customContexts.get(oldKey)); + } + } + } + return new ApiCallCustomContexts(builder.build()); + } + + /** Get a custom context. */ + public T getCustomContext(Key key) { + Preconditions.checkNotNull(key); + if (!customContexts.containsKey(key)) { + return key.getDefault(); + } + return (T) customContexts.get(key); + } + + /** + * Merge new custom contexts into existing custom contexts. Any existing values of the keys are + * overwritten. + */ + public ApiCallCustomContexts merge(ApiCallCustomContexts newCustomContexts) { + Preconditions.checkNotNull(newCustomContexts); + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (Key key : customContexts.keySet()) { + Object oldValue = customContexts.get(key); + Object newValue = newCustomContexts.customContexts.get(key); + builder.put(key, newValue != null ? newValue : oldValue); + } + for (Key key : newCustomContexts.customContexts.keySet()) { + if (!customContexts.containsKey(key)) { + builder.put(key, newCustomContexts.customContexts.get(key)); + } + } + return new ApiCallCustomContexts(builder.build()); + } +} diff --git a/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java b/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java index 08fb27505..2ad100095 100644 --- a/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java +++ b/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java @@ -35,7 +35,7 @@ import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; -import com.google.api.gax.rpc.internal.ApiCallContextUtil; +import com.google.api.gax.rpc.internal.ApiCallCustomContexts; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -58,7 +58,7 @@ public class FakeCallContext implements ApiCallContext { private final Duration streamWaitTimeout; private final Duration streamIdleTimeout; private final ImmutableMap> extraHeaders; - private final ImmutableMap extraContexts; + private final ApiCallCustomContexts customContexts; private final ApiTracer tracer; private final RetrySettings retrySettings; private final ImmutableSet retryableCodes; @@ -70,7 +70,7 @@ private FakeCallContext( Duration streamWaitTimeout, Duration streamIdleTimeout, ImmutableMap> extraHeaders, - ImmutableMap extraContexts, + ApiCallCustomContexts customContexts, ApiTracer tracer, RetrySettings retrySettings, Set retryableCodes) { @@ -80,7 +80,7 @@ private FakeCallContext( this.streamWaitTimeout = streamWaitTimeout; this.streamIdleTimeout = streamIdleTimeout; this.extraHeaders = extraHeaders; - this.extraContexts = extraContexts; + this.customContexts = customContexts; this.tracer = tracer; this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); @@ -94,7 +94,7 @@ public static FakeCallContext createDefault() { null, null, ImmutableMap.>of(), - ImmutableMap.of(), + ApiCallCustomContexts.createDefault(), null, null, null); @@ -171,8 +171,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(extraHeaders, fakeCallContext.extraHeaders); - ImmutableMap newExtraContext = - ApiCallContextUtil.mergeExtraContexts(extraContexts, fakeCallContext.extraContexts); + ApiCallCustomContexts newCustomContext = customContexts.merge(fakeCallContext.customContexts); return new FakeCallContext( newCallCredentials, @@ -181,7 +180,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { newStreamWaitTimeout, newStreamIdleTimeout, newExtraHeaders, - newExtraContext, + newCustomContext, newTracer, newRetrySettings, newRetryableCodes); @@ -199,7 +198,7 @@ public FakeCallContext withRetrySettings(RetrySettings retrySettings) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, retrySettings, this.retryableCodes); @@ -217,7 +216,7 @@ public FakeCallContext withRetryableCodes(Set retryableCodes) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, retryableCodes); @@ -257,7 +256,7 @@ public FakeCallContext withCredentials(Credentials credentials) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -282,7 +281,7 @@ public FakeCallContext withChannel(FakeChannel channel) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -307,7 +306,7 @@ public FakeCallContext withTimeout(Duration timeout) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -322,7 +321,7 @@ public ApiCallContext withStreamWaitTimeout(@Nullable Duration streamWaitTimeout streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -338,7 +337,7 @@ public ApiCallContext withStreamIdleTimeout(@Nullable Duration streamIdleTimeout this.streamWaitTimeout, streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -356,7 +355,7 @@ public ApiCallContext withExtraHeaders(Map> extraHeaders) { streamWaitTimeout, streamIdleTimeout, newExtraHeaders, - this.extraContexts, + this.customContexts, this.tracer, this.retrySettings, this.retryableCodes); @@ -368,10 +367,9 @@ public Map> getExtraHeaders() { } @Override - public ApiCallContext withExtraContext(Key key, T extraContext) { + public ApiCallContext withCustomContext(Key key, T value) { Preconditions.checkNotNull(key); - ImmutableMap newExtraContexts = - ApiCallContextUtil.addExtraContext(extraContexts, key, extraContext); + ApiCallCustomContexts newCustomContexts = customContexts.withCustomContext(key, value); return new FakeCallContext( credentials, channel, @@ -379,19 +377,16 @@ public ApiCallContext withExtraContext(Key key, T extraContext) { streamWaitTimeout, streamIdleTimeout, extraHeaders, - newExtraContexts, + newCustomContexts, tracer, retrySettings, retryableCodes); } @Override - public T getExtraContext(Key key) { + public T getCustomContext(Key key) { Preconditions.checkNotNull(key); - if (extraContexts.containsKey(key)) { - return (T) extraContexts.get(key); - } - return key.getDefault(); + return customContexts.getCustomContext(key); } /** {@inheritDoc} */ @@ -416,7 +411,7 @@ public ApiCallContext withTracer(@Nonnull ApiTracer tracer) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.extraContexts, + this.customContexts, tracer, this.retrySettings, this.retryableCodes); From a385df676083485f063eed17d9d344ed757518b6 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Fri, 30 Jul 2021 16:31:08 +0000 Subject: [PATCH 3/8] make variable final --- .../com/google/api/gax/rpc/internal/ApiCallCustomContexts.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java index 002f96828..a054d804b 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java @@ -39,7 +39,7 @@ @InternalApi public final class ApiCallCustomContexts { - private ImmutableMap customContexts; + private final ImmutableMap customContexts; private ApiCallCustomContexts(ImmutableMap contexts) { this.customContexts = Preconditions.checkNotNull(contexts); From 73bc7b1ae9f39e7658952afa6e56861c7504ede1 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Wed, 4 Aug 2021 21:18:51 +0000 Subject: [PATCH 4/8] renaming classes --- .../google/api/gax/grpc/GrpcCallContext.java | 48 ++++++------- .../api/gax/grpc/GrpcCallContextTest.java | 30 ++++---- .../api/gax/httpjson/HttpJsonCallContext.java | 45 ++++++------ .../gax/httpjson/HttpJsonCallContextTest.java | 30 ++++---- .../google/api/gax/rpc/ApiCallContext.java | 22 +++--- ...ntexts.java => ApiCallContextOptions.java} | 69 +++++++++---------- .../api/gax/rpc/testing/FakeCallContext.java | 42 +++++------ 7 files changed, 138 insertions(+), 148 deletions(-) rename gax/src/main/java/com/google/api/gax/rpc/internal/{ApiCallCustomContexts.java => ApiCallContextOptions.java} (53%) diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java index 81648795b..d3fdd990e 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java @@ -34,7 +34,7 @@ import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; -import com.google.api.gax.rpc.internal.ApiCallCustomContexts; +import com.google.api.gax.rpc.internal.ApiCallContextOptions; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -77,7 +77,7 @@ public final class GrpcCallContext implements ApiCallContext { @Nullable private final RetrySettings retrySettings; @Nullable private final ImmutableSet retryableCodes; private final ImmutableMap> extraHeaders; - private final ApiCallCustomContexts customContexts; + private final ApiCallContextOptions options; /** Returns an empty instance with a null channel and default {@link CallOptions}. */ public static GrpcCallContext createDefault() { @@ -89,7 +89,7 @@ public static GrpcCallContext createDefault() { null, null, ImmutableMap.>of(), - ApiCallCustomContexts.createDefault(), + ApiCallContextOptions.getDefaultOptions(), null, null); } @@ -104,7 +104,7 @@ public static GrpcCallContext of(Channel channel, CallOptions callOptions) { null, null, ImmutableMap.>of(), - ApiCallCustomContexts.createDefault(), + ApiCallContextOptions.getDefaultOptions(), null, null); } @@ -117,7 +117,7 @@ private GrpcCallContext( @Nullable Duration streamIdleTimeout, @Nullable Integer channelAffinity, ImmutableMap> extraHeaders, - ApiCallCustomContexts customContexts, + ApiCallContextOptions options, @Nullable RetrySettings retrySettings, @Nullable Set retryableCodes) { this.channel = channel; @@ -127,7 +127,7 @@ private GrpcCallContext( this.streamIdleTimeout = streamIdleTimeout; this.channelAffinity = channelAffinity; this.extraHeaders = Preconditions.checkNotNull(extraHeaders); - this.customContexts = Preconditions.checkNotNull(customContexts); + this.options = Preconditions.checkNotNull(options); this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); } @@ -192,7 +192,7 @@ public GrpcCallContext withTimeout(@Nullable Duration timeout) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.customContexts, + this.options, this.retrySettings, this.retryableCodes); } @@ -218,7 +218,7 @@ public GrpcCallContext withStreamWaitTimeout(@Nullable Duration streamWaitTimeou this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.customContexts, + this.options, this.retrySettings, this.retryableCodes); } @@ -238,7 +238,7 @@ public GrpcCallContext withStreamIdleTimeout(@Nullable Duration streamIdleTimeou streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.customContexts, + this.options, this.retrySettings, this.retryableCodes); } @@ -253,7 +253,7 @@ public GrpcCallContext withChannelAffinity(@Nullable Integer affinity) { this.streamIdleTimeout, affinity, this.extraHeaders, - this.customContexts, + this.options, this.retrySettings, this.retryableCodes); } @@ -272,7 +272,7 @@ public GrpcCallContext withExtraHeaders(Map> extraHeaders) this.streamIdleTimeout, this.channelAffinity, newExtraHeaders, - this.customContexts, + this.options, this.retrySettings, this.retryableCodes); } @@ -292,7 +292,7 @@ public GrpcCallContext withRetrySettings(RetrySettings retrySettings) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.customContexts, + this.options, retrySettings, this.retryableCodes); } @@ -312,7 +312,7 @@ public GrpcCallContext withRetryableCodes(Set retryableCodes) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.customContexts, + this.options, this.retrySettings, retryableCodes); } @@ -382,7 +382,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(this.extraHeaders, grpcCallContext.extraHeaders); - ApiCallCustomContexts newCustomContexts = customContexts.merge(grpcCallContext.customContexts); + ApiCallContextOptions newOptions = options.merge(grpcCallContext.options); CallOptions newCallOptions = grpcCallContext @@ -402,7 +402,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { newStreamIdleTimeout, newChannelAffinity, newExtraHeaders, - newCustomContexts, + newOptions, newRetrySettings, newRetryableCodes); } @@ -463,7 +463,7 @@ public GrpcCallContext withChannel(Channel newChannel) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.customContexts, + this.options, this.retrySettings, this.retryableCodes); } @@ -478,7 +478,7 @@ public GrpcCallContext withCallOptions(CallOptions newCallOptions) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - this.customContexts, + this.options, this.retrySettings, this.retryableCodes); } @@ -510,8 +510,8 @@ public GrpcCallContext withTracer(@Nonnull ApiTracer tracer) { /** {@inheritDoc} */ @Override - public GrpcCallContext withCustomContext(Key key, T value) { - ApiCallCustomContexts newCustomContexts = customContexts.withCustomContext(key, value); + public GrpcCallContext withOption(Key key, T value) { + ApiCallContextOptions newOptions = options.withOption(key, value); return new GrpcCallContext( this.channel, this.callOptions, @@ -520,15 +520,15 @@ public GrpcCallContext withCustomContext(Key key, T value) { this.streamIdleTimeout, this.channelAffinity, this.extraHeaders, - newCustomContexts, + newOptions, this.retrySettings, this.retryableCodes); } /** {@inheritDoc} */ @Override - public T getCustomContext(Key key) { - return customContexts.getCustomContext(key); + public T getOption(Key key) { + return options.getOption(key); } @Override @@ -541,7 +541,7 @@ public int hashCode() { streamIdleTimeout, channelAffinity, extraHeaders, - customContexts, + options, retrySettings, retryableCodes); } @@ -563,7 +563,7 @@ public boolean equals(Object o) { && Objects.equals(this.streamIdleTimeout, that.streamIdleTimeout) && Objects.equals(this.channelAffinity, that.channelAffinity) && Objects.equals(this.extraHeaders, that.extraHeaders) - && Objects.equals(this.customContexts, that.customContexts) + && Objects.equals(this.options, that.options) && Objects.equals(this.retrySettings, that.retrySettings) && Objects.equals(this.retryableCodes, that.retryableCodes); } diff --git a/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java b/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java index f07731601..4e563225e 100644 --- a/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java +++ b/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcCallContextTest.java @@ -355,7 +355,7 @@ public void testWithRetryableCodes() { } @Test - public void testWithCustomContexts() { + public void testWithOptions() { GrpcCallContext emptyCallContext = GrpcCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -364,16 +364,16 @@ public void testWithCustomContexts() { String testContextOverwrite = "test1Overwrite"; GrpcCallContext context = emptyCallContext - .withCustomContext(contextKey1, testContext1) - .withCustomContext(contextKey2, testContext2); - assertEquals(testContext1, context.getCustomContext(contextKey1)); - assertEquals(testContext2, context.getCustomContext(contextKey2)); - GrpcCallContext newContext = context.withCustomContext(contextKey1, testContextOverwrite); - assertEquals(testContextOverwrite, newContext.getCustomContext(contextKey1)); + .withOption(contextKey1, testContext1) + .withOption(contextKey2, testContext2); + assertEquals(testContext1, context.getOption(contextKey1)); + assertEquals(testContext2, context.getOption(contextKey2)); + GrpcCallContext newContext = context.withOption(contextKey1, testContextOverwrite); + assertEquals(testContextOverwrite, newContext.getOption(contextKey1)); } @Test - public void testMergeCustomContexts() { + public void testMergeOptions() { GrpcCallContext emptyCallContext = GrpcCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -384,16 +384,16 @@ public void testMergeCustomContexts() { String testContextOverwrite = "test1Overwrite"; GrpcCallContext context1 = emptyCallContext - .withCustomContext(contextKey1, testContext1) - .withCustomContext(contextKey2, testContext2); + .withOption(contextKey1, testContext1) + .withOption(contextKey2, testContext2); GrpcCallContext context2 = emptyCallContext - .withCustomContext(contextKey1, testContextOverwrite) - .withCustomContext(contextKey3, testContext3); + .withOption(contextKey1, testContextOverwrite) + .withOption(contextKey3, testContext3); ApiCallContext mergedContext = context1.merge(context2); - assertEquals(testContextOverwrite, mergedContext.getCustomContext(contextKey1)); - assertEquals(testContext2, mergedContext.getCustomContext(contextKey2)); - assertEquals(testContext3, mergedContext.getCustomContext(contextKey3)); + assertEquals(testContextOverwrite, mergedContext.getOption(contextKey1)); + assertEquals(testContext2, mergedContext.getOption(contextKey2)); + assertEquals(testContext3, mergedContext.getOption(contextKey3)); } private static Map> createTestExtraHeaders(String... keyValues) { diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java index 84edbda79..0d3b00898 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java @@ -34,7 +34,7 @@ import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; -import com.google.api.gax.rpc.internal.ApiCallCustomContexts; +import com.google.api.gax.rpc.internal.ApiCallContextOptions; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -66,7 +66,7 @@ public final class HttpJsonCallContext implements ApiCallContext { private final Instant deadline; private final Credentials credentials; private final ImmutableMap> extraHeaders; - private final ApiCallCustomContexts customContexts; + private final ApiCallContextOptions options; private final ApiTracer tracer; private final RetrySettings retrySettings; private final ImmutableSet retryableCodes; @@ -79,7 +79,7 @@ public static HttpJsonCallContext createDefault() { null, null, ImmutableMap.>of(), - ApiCallCustomContexts.createDefault(), + ApiCallContextOptions.getDefaultOptions(), null, null, null); @@ -91,7 +91,7 @@ private HttpJsonCallContext( Instant deadline, Credentials credentials, ImmutableMap> extraHeaders, - ApiCallCustomContexts customContexts, + ApiCallContextOptions options, ApiTracer tracer, RetrySettings defaultRetrySettings, Set defaultRetryableCodes) { @@ -100,7 +100,7 @@ private HttpJsonCallContext( this.deadline = deadline; this.credentials = credentials; this.extraHeaders = extraHeaders; - this.customContexts = customContexts; + this.options = options; this.tracer = tracer; this.retrySettings = defaultRetrySettings; this.retryableCodes = @@ -164,8 +164,7 @@ public HttpJsonCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(extraHeaders, httpJsonCallContext.extraHeaders); - ApiCallCustomContexts newCustomContext = - customContexts.merge(httpJsonCallContext.customContexts); + ApiCallContextOptions newOptions = options.merge(httpJsonCallContext.options); ApiTracer newTracer = httpJsonCallContext.tracer; if (newTracer == null) { @@ -188,7 +187,7 @@ public HttpJsonCallContext merge(ApiCallContext inputCallContext) { newDeadline, newCredentials, newExtraHeaders, - newCustomContext, + newOptions, newTracer, newRetrySettings, newRetryableCodes); @@ -202,7 +201,7 @@ public HttpJsonCallContext withCredentials(Credentials newCredentials) { this.deadline, newCredentials, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -237,7 +236,7 @@ public HttpJsonCallContext withTimeout(Duration timeout) { this.deadline, this.credentials, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -283,7 +282,7 @@ public ApiCallContext withExtraHeaders(Map> extraHeaders) { this.deadline, this.credentials, newExtraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -297,15 +296,15 @@ public Map> getExtraHeaders() { /** {@inheritDoc} */ @Override - public ApiCallContext withCustomContext(Key key, T value) { - ApiCallCustomContexts newCustomContexts = customContexts.withCustomContext(key, value); + public ApiCallContext withOption(Key key, T value) { + ApiCallContextOptions newOptions = options.withOption(key, value); return new HttpJsonCallContext( this.channel, this.timeout, this.deadline, this.credentials, this.extraHeaders, - newCustomContexts, + newOptions, this.tracer, this.retrySettings, this.retryableCodes); @@ -313,8 +312,8 @@ public ApiCallContext withCustomContext(Key key, T value) { /** {@inheritDoc} */ @Override - public T getCustomContext(Key key) { - return customContexts.getCustomContext(key); + public T getOption(Key key) { + return options.getOption(key); } public HttpJsonChannel getChannel() { @@ -342,7 +341,7 @@ public HttpJsonCallContext withRetrySettings(RetrySettings retrySettings) { this.deadline, this.credentials, this.extraHeaders, - this.customContexts, + this.options, this.tracer, retrySettings, this.retryableCodes); @@ -361,7 +360,7 @@ public HttpJsonCallContext withRetryableCodes(Set retryableCode this.deadline, this.credentials, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, retryableCodes); @@ -374,7 +373,7 @@ public HttpJsonCallContext withChannel(HttpJsonChannel newChannel) { this.deadline, this.credentials, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -387,7 +386,7 @@ public HttpJsonCallContext withDeadline(Instant newDeadline) { newDeadline, this.credentials, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -413,7 +412,7 @@ public HttpJsonCallContext withTracer(@Nonnull ApiTracer newTracer) { this.deadline, this.credentials, this.extraHeaders, - this.customContexts, + this.options, newTracer, this.retrySettings, this.retryableCodes); @@ -433,7 +432,7 @@ public boolean equals(Object o) { && Objects.equals(this.deadline, that.deadline) && Objects.equals(this.credentials, that.credentials) && Objects.equals(this.extraHeaders, that.extraHeaders) - && Objects.equals(this.customContexts, that.customContexts) + && Objects.equals(this.options, that.options) && Objects.equals(this.tracer, that.tracer) && Objects.equals(this.retrySettings, that.retrySettings) && Objects.equals(this.retryableCodes, that.retryableCodes); @@ -447,7 +446,7 @@ public int hashCode() { deadline, credentials, extraHeaders, - customContexts, + options, tracer, retrySettings, retryableCodes); diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java index 426aa9cc3..fc872d352 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonCallContextTest.java @@ -231,7 +231,7 @@ public void testWithExtraHeaders() { } @Test - public void testWithCustomContexts() { + public void testWithOptions() { ApiCallContext emptyCallContext = HttpJsonCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -240,16 +240,16 @@ public void testWithCustomContexts() { String testContextOverwrite = "test1Overwrite"; ApiCallContext context = emptyCallContext - .withCustomContext(contextKey1, testContext1) - .withCustomContext(contextKey2, testContext2); - assertEquals(testContext1, context.getCustomContext(contextKey1)); - assertEquals(testContext2, context.getCustomContext(contextKey2)); - ApiCallContext newContext = context.withCustomContext(contextKey1, testContextOverwrite); - assertEquals(testContextOverwrite, newContext.getCustomContext(contextKey1)); + .withOption(contextKey1, testContext1) + .withOption(contextKey2, testContext2); + assertEquals(testContext1, context.getOption(contextKey1)); + assertEquals(testContext2, context.getOption(contextKey2)); + ApiCallContext newContext = context.withOption(contextKey1, testContextOverwrite); + assertEquals(testContextOverwrite, newContext.getOption(contextKey1)); } @Test - public void testMergeCustomContexts() { + public void testMergeOptions() { ApiCallContext emptyCallContext = HttpJsonCallContext.createDefault(); ApiCallContext.Key contextKey1 = ApiCallContext.Key.create("testKey1"); ApiCallContext.Key contextKey2 = ApiCallContext.Key.create("testKey2"); @@ -260,15 +260,15 @@ public void testMergeCustomContexts() { String testContextOverwrite = "test1Overwrite"; ApiCallContext context1 = emptyCallContext - .withCustomContext(contextKey1, testContext1) - .withCustomContext(contextKey2, testContext2); + .withOption(contextKey1, testContext1) + .withOption(contextKey2, testContext2); ApiCallContext context2 = emptyCallContext - .withCustomContext(contextKey1, testContextOverwrite) - .withCustomContext(contextKey3, testContext3); + .withOption(contextKey1, testContextOverwrite) + .withOption(contextKey3, testContext3); ApiCallContext mergedContext = context1.merge(context2); - assertEquals(testContextOverwrite, mergedContext.getCustomContext(contextKey1)); - assertEquals(testContext2, mergedContext.getCustomContext(contextKey2)); - assertEquals(testContext3, mergedContext.getCustomContext(contextKey3)); + assertEquals(testContextOverwrite, mergedContext.getOption(contextKey1)); + assertEquals(testContext2, mergedContext.getOption(contextKey2)); + assertEquals(testContext3, mergedContext.getOption(contextKey3)); } } diff --git a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java index 5c7a07af2..61ec4892d 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java +++ b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java @@ -245,18 +245,20 @@ public interface ApiCallContext extends RetryingContext { Map> getExtraHeaders(); /** - * Return a new ApiCallContext with the custom context merged into the present instance. Any + * Return a new ApiCallContext with additional option merged into the present instance. Any * existing value of the key is overwritten. */ - @BetaApi("The surface for custom contexts is not stable yet and may change in the future.") - ApiCallContext withCustomContext(Key key, T value); + @BetaApi( + "The surface for api call context options is not stable yet and may change in the future.") + ApiCallContext withOption(Key key, T value); - /** Return the custom context set for this context. */ + /** Return the api call context option set for this context. */ @SuppressWarnings("unchecked") - @BetaApi("The surface for custom contexts is not stable yet and may change in the future.") - T getCustomContext(Key key); + @BetaApi( + "The surface for api call context options is not stable yet and may change in the future.") + T getOption(Key key); - /** Key for custom contexts key-value pair. */ + /** Key for api call context options key-value pair. */ final class Key { private final String name; private final T defaultValue; @@ -274,12 +276,6 @@ public static Key create(String name) { return new Key<>(name, null); } - /** Factory method for creating instances of {@link Key} with default values. */ - public static Key createWithDefault(String name, T defaultValue) { - Preconditions.checkNotNull(name, "Key name cannot be null."); - return new Key<>(name, defaultValue); - } - /** Returns the user supplied default value of the key. */ public T getDefault() { return defaultValue; diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java similarity index 53% rename from gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java rename to gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java index a054d804b..987e33736 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallCustomContexts.java +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java @@ -35,66 +35,61 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; -/** ApiCallCustomContexts encapsulates custom context data to pass in a {@link ApiCallContext} */ +/** + * ApiCallContextOptions encapsulates additional call options to pass in a {@link ApiCallContext} + */ @InternalApi -public final class ApiCallCustomContexts { +public final class ApiCallContextOptions { - private final ImmutableMap customContexts; + private final ImmutableMap options; + private static final ApiCallContextOptions DEFAULT_OPTIONS = + new ApiCallContextOptions(ImmutableMap.of()); - private ApiCallCustomContexts(ImmutableMap contexts) { - this.customContexts = Preconditions.checkNotNull(contexts); + private ApiCallContextOptions(ImmutableMap contexts) { + this.options = Preconditions.checkNotNull(contexts); } - /** Create an empty custom call context. */ - public static ApiCallCustomContexts createDefault() { - return new ApiCallCustomContexts(ImmutableMap.of()); + public static ApiCallContextOptions getDefaultOptions() { + return DEFAULT_OPTIONS; } - /** Add a context to custom contexts. Any existing value of the key is overwritten. */ - public ApiCallCustomContexts withCustomContext(Key key, T context) { + /** Add an option. Any existing value of the key is overwritten. */ + public ApiCallContextOptions withOption(Key key, T value) { Preconditions.checkNotNull(key); - Preconditions.checkNotNull(context); + Preconditions.checkNotNull(value); ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!customContexts.containsKey(key)) { - builder.putAll(customContexts).put(key, context); + if (!options.containsKey(key)) { + builder.putAll(options).put(key, value); } else { - for (Key oldKey : customContexts.keySet()) { + for (Key oldKey : options.keySet()) { if (oldKey.equals(key)) { - builder.put(oldKey, context); + builder.put(oldKey, value); } else { - builder.put(oldKey, customContexts.get(oldKey)); + builder.put(oldKey, options.get(oldKey)); } } } - return new ApiCallCustomContexts(builder.build()); + return new ApiCallContextOptions(builder.build()); } - /** Get a custom context. */ - public T getCustomContext(Key key) { + /** Get an option. */ + public T getOption(Key key) { Preconditions.checkNotNull(key); - if (!customContexts.containsKey(key)) { + if (!options.containsKey(key)) { return key.getDefault(); } - return (T) customContexts.get(key); + return (T) options.get(key); } - /** - * Merge new custom contexts into existing custom contexts. Any existing values of the keys are - * overwritten. - */ - public ApiCallCustomContexts merge(ApiCallCustomContexts newCustomContexts) { - Preconditions.checkNotNull(newCustomContexts); - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (Key key : customContexts.keySet()) { - Object oldValue = customContexts.get(key); - Object newValue = newCustomContexts.customContexts.get(key); - builder.put(key, newValue != null ? newValue : oldValue); - } - for (Key key : newCustomContexts.customContexts.keySet()) { - if (!customContexts.containsKey(key)) { - builder.put(key, newCustomContexts.customContexts.get(key)); + /** Merge new options into existing ones. Any existing values of the keys are overwritten. */ + public ApiCallContextOptions merge(ApiCallContextOptions newOptions) { + Preconditions.checkNotNull(newOptions); + ImmutableMap.Builder builder = ImmutableMap.builder().putAll(newOptions.options); + for (Key key : options.keySet()) { + if (!newOptions.options.containsKey(key)) { + builder.put(key, options.get(key)); } } - return new ApiCallCustomContexts(builder.build()); + return new ApiCallContextOptions(builder.build()); } } diff --git a/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java b/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java index 2ad100095..84d40e11c 100644 --- a/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java +++ b/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java @@ -35,7 +35,7 @@ import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.TransportChannel; -import com.google.api.gax.rpc.internal.ApiCallCustomContexts; +import com.google.api.gax.rpc.internal.ApiCallContextOptions; import com.google.api.gax.rpc.internal.Headers; import com.google.api.gax.tracing.ApiTracer; import com.google.api.gax.tracing.BaseApiTracer; @@ -58,7 +58,7 @@ public class FakeCallContext implements ApiCallContext { private final Duration streamWaitTimeout; private final Duration streamIdleTimeout; private final ImmutableMap> extraHeaders; - private final ApiCallCustomContexts customContexts; + private final ApiCallContextOptions options; private final ApiTracer tracer; private final RetrySettings retrySettings; private final ImmutableSet retryableCodes; @@ -70,7 +70,7 @@ private FakeCallContext( Duration streamWaitTimeout, Duration streamIdleTimeout, ImmutableMap> extraHeaders, - ApiCallCustomContexts customContexts, + ApiCallContextOptions options, ApiTracer tracer, RetrySettings retrySettings, Set retryableCodes) { @@ -80,7 +80,7 @@ private FakeCallContext( this.streamWaitTimeout = streamWaitTimeout; this.streamIdleTimeout = streamIdleTimeout; this.extraHeaders = extraHeaders; - this.customContexts = customContexts; + this.options = options; this.tracer = tracer; this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); @@ -94,7 +94,7 @@ public static FakeCallContext createDefault() { null, null, ImmutableMap.>of(), - ApiCallCustomContexts.createDefault(), + ApiCallContextOptions.getDefaultOptions(), null, null, null); @@ -171,7 +171,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { ImmutableMap> newExtraHeaders = Headers.mergeHeaders(extraHeaders, fakeCallContext.extraHeaders); - ApiCallCustomContexts newCustomContext = customContexts.merge(fakeCallContext.customContexts); + ApiCallContextOptions newOptions = options.merge(fakeCallContext.options); return new FakeCallContext( newCallCredentials, @@ -180,7 +180,7 @@ public ApiCallContext merge(ApiCallContext inputCallContext) { newStreamWaitTimeout, newStreamIdleTimeout, newExtraHeaders, - newCustomContext, + newOptions, newTracer, newRetrySettings, newRetryableCodes); @@ -198,7 +198,7 @@ public FakeCallContext withRetrySettings(RetrySettings retrySettings) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, this.tracer, retrySettings, this.retryableCodes); @@ -216,7 +216,7 @@ public FakeCallContext withRetryableCodes(Set retryableCodes) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, retryableCodes); @@ -256,7 +256,7 @@ public FakeCallContext withCredentials(Credentials credentials) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -281,7 +281,7 @@ public FakeCallContext withChannel(FakeChannel channel) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -306,7 +306,7 @@ public FakeCallContext withTimeout(Duration timeout) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -321,7 +321,7 @@ public ApiCallContext withStreamWaitTimeout(@Nullable Duration streamWaitTimeout streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -337,7 +337,7 @@ public ApiCallContext withStreamIdleTimeout(@Nullable Duration streamIdleTimeout this.streamWaitTimeout, streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -355,7 +355,7 @@ public ApiCallContext withExtraHeaders(Map> extraHeaders) { streamWaitTimeout, streamIdleTimeout, newExtraHeaders, - this.customContexts, + this.options, this.tracer, this.retrySettings, this.retryableCodes); @@ -367,9 +367,9 @@ public Map> getExtraHeaders() { } @Override - public ApiCallContext withCustomContext(Key key, T value) { + public ApiCallContext withOption(Key key, T value) { Preconditions.checkNotNull(key); - ApiCallCustomContexts newCustomContexts = customContexts.withCustomContext(key, value); + ApiCallContextOptions newOptions = options.withOption(key, value); return new FakeCallContext( credentials, channel, @@ -377,16 +377,16 @@ public ApiCallContext withCustomContext(Key key, T value) { streamWaitTimeout, streamIdleTimeout, extraHeaders, - newCustomContexts, + newOptions, tracer, retrySettings, retryableCodes); } @Override - public T getCustomContext(Key key) { + public T getOption(Key key) { Preconditions.checkNotNull(key); - return customContexts.getCustomContext(key); + return options.getOption(key); } /** {@inheritDoc} */ @@ -411,7 +411,7 @@ public ApiCallContext withTracer(@Nonnull ApiTracer tracer) { this.streamWaitTimeout, this.streamIdleTimeout, this.extraHeaders, - this.customContexts, + this.options, tracer, this.retrySettings, this.retryableCodes); From ccddcdcc3bf8c7a32f43c31877b6ca61a34b9d94 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Wed, 4 Aug 2021 21:29:08 +0000 Subject: [PATCH 5/8] remove default key value --- .../google/api/gax/rpc/ApiCallContext.java | 21 +++++-------------- .../rpc/internal/ApiCallContextOptions.java | 2 +- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java index 61ec4892d..79e4ef0e7 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java +++ b/gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java @@ -248,37 +248,26 @@ public interface ApiCallContext extends RetryingContext { * Return a new ApiCallContext with additional option merged into the present instance. Any * existing value of the key is overwritten. */ - @BetaApi( - "The surface for api call context options is not stable yet and may change in the future.") + @BetaApi("The surface for call context options is not stable yet and may change in the future.") ApiCallContext withOption(Key key, T value); /** Return the api call context option set for this context. */ @SuppressWarnings("unchecked") - @BetaApi( - "The surface for api call context options is not stable yet and may change in the future.") + @BetaApi("The surface for call context options is not stable yet and may change in the future.") T getOption(Key key); /** Key for api call context options key-value pair. */ final class Key { private final String name; - private final T defaultValue; - private Key(String name, T defaultValue) { + private Key(String name) { this.name = name; - this.defaultValue = defaultValue; } - /** - * Factory method for creating instances of {@link Key}. The default value of the key is null. - */ + /** Factory method for creating instances of {@link Key}. */ public static Key create(String name) { Preconditions.checkNotNull(name, "Key name cannot be null."); - return new Key<>(name, null); - } - - /** Returns the user supplied default value of the key. */ - public T getDefault() { - return defaultValue; + return new Key<>(name); } } } diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java index 987e33736..b1b399f49 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java @@ -76,7 +76,7 @@ public ApiCallContextOptions withOption(Key key, T value) { public T getOption(Key key) { Preconditions.checkNotNull(key); if (!options.containsKey(key)) { - return key.getDefault(); + return null; } return (T) options.get(key); } From 0a50c8c482fd81969b4e5bce00b60b579526921d Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Wed, 4 Aug 2021 21:43:27 +0000 Subject: [PATCH 6/8] update --- .../com/google/api/gax/rpc/internal/ApiCallContextOptions.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java index b1b399f49..e536e71ac 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java @@ -75,9 +75,6 @@ public ApiCallContextOptions withOption(Key key, T value) { /** Get an option. */ public T getOption(Key key) { Preconditions.checkNotNull(key); - if (!options.containsKey(key)) { - return null; - } return (T) options.get(key); } From cffdbc9c9aaee5126a62fd0ba4223e22b17029a9 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Thu, 5 Aug 2021 17:55:24 +0000 Subject: [PATCH 7/8] fix parameter name --- .../google/api/gax/rpc/internal/ApiCallContextOptions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java index e536e71ac..14c20b1ad 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java @@ -45,8 +45,8 @@ public final class ApiCallContextOptions { private static final ApiCallContextOptions DEFAULT_OPTIONS = new ApiCallContextOptions(ImmutableMap.of()); - private ApiCallContextOptions(ImmutableMap contexts) { - this.options = Preconditions.checkNotNull(contexts); + private ApiCallContextOptions(ImmutableMap options) { + this.options = Preconditions.checkNotNull(options); } public static ApiCallContextOptions getDefaultOptions() { From 960807bb03037419446a4c84a02fb772d55eba6b Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Fri, 13 Aug 2021 15:00:06 +0000 Subject: [PATCH 8/8] add ApiCallContextOptions tests --- .../rpc/internal/ApiCallContextOptions.java | 5 +- .../internal/ApiCallContextOptionsTest.java | 110 ++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 gax/src/test/java/com/google/api/gax/rpc/internal/ApiCallContextOptionsTest.java diff --git a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java index 14c20b1ad..daf64679c 100644 --- a/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java +++ b/gax/src/main/java/com/google/api/gax/rpc/internal/ApiCallContextOptions.java @@ -61,10 +61,9 @@ public ApiCallContextOptions withOption(Key key, T value) { if (!options.containsKey(key)) { builder.putAll(options).put(key, value); } else { + builder.put(key, value); for (Key oldKey : options.keySet()) { - if (oldKey.equals(key)) { - builder.put(oldKey, value); - } else { + if (!oldKey.equals(key)) { builder.put(oldKey, options.get(oldKey)); } } diff --git a/gax/src/test/java/com/google/api/gax/rpc/internal/ApiCallContextOptionsTest.java b/gax/src/test/java/com/google/api/gax/rpc/internal/ApiCallContextOptionsTest.java new file mode 100644 index 000000000..cf4f785bb --- /dev/null +++ b/gax/src/test/java/com/google/api/gax/rpc/internal/ApiCallContextOptionsTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2021 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.api.gax.rpc.internal; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.api.gax.rpc.ApiCallContext; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ApiCallContextOptionsTest { + + private static final ApiCallContext.Key INTEGER_KEY = ApiCallContext.Key.create("key1"); + private static final ApiCallContext.Key STRING_KEY = ApiCallContext.Key.create("key2"); + private static final ApiCallContext.Key DOUBLE_KEY = ApiCallContext.Key.create("key3"); + + @Test + public void testWithOption() { + ApiCallContextOptions options = + ApiCallContextOptions.getDefaultOptions() + .withOption(INTEGER_KEY, 1) + .withOption(STRING_KEY, "test") + .withOption(DOUBLE_KEY, 2.0); + assertThat(options.getOption(INTEGER_KEY)).isEqualTo(1); + assertThat(options.getOption(STRING_KEY)).isEqualTo("test"); + assertThat(options.getOption(DOUBLE_KEY)).isEqualTo(2.0); + + ApiCallContextOptions updatedOptions = options.withOption(INTEGER_KEY, 10); + assertThat(updatedOptions.getOption(INTEGER_KEY)).isEqualTo(10); + assertThat(options.getOption(STRING_KEY)).isEqualTo("test"); + assertThat(options.getOption(DOUBLE_KEY)).isEqualTo(2.0); + } + + @Test + public void testMergeEmpty() { + ApiCallContextOptions options = + ApiCallContextOptions.getDefaultOptions() + .withOption(INTEGER_KEY, 1) + .withOption(STRING_KEY, "test"); + + ApiCallContextOptions defaultOptions = ApiCallContextOptions.getDefaultOptions(); + + ApiCallContextOptions mergedOptions1 = options.merge(defaultOptions); + assertThat(mergedOptions1.getOption(INTEGER_KEY)).isEqualTo(1); + assertThat(mergedOptions1.getOption(STRING_KEY)).isEqualTo("test"); + + ApiCallContextOptions mergedOptions2 = defaultOptions.merge(options); + assertThat(mergedOptions2.getOption(INTEGER_KEY)).isEqualTo(1); + assertThat(mergedOptions2.getOption(STRING_KEY)).isEqualTo("test"); + } + + @Test + public void testMergeDifferentKeys() { + ApiCallContextOptions options1 = + ApiCallContextOptions.getDefaultOptions() + .withOption(INTEGER_KEY, 1) + .withOption(STRING_KEY, "test"); + ApiCallContextOptions options2 = + ApiCallContextOptions.getDefaultOptions().withOption(DOUBLE_KEY, 5.0); + ApiCallContextOptions mergedOptions = options1.merge(options2); + assertThat(mergedOptions.getOption(INTEGER_KEY)).isEqualTo(1); + assertThat(mergedOptions.getOption(STRING_KEY)).isEqualTo("test"); + assertThat(mergedOptions.getOption(DOUBLE_KEY)).isEqualTo(5.0); + } + + @Test + public void testMergeDuplicateKeys() { + ApiCallContextOptions options1 = + ApiCallContextOptions.getDefaultOptions() + .withOption(INTEGER_KEY, 1) + .withOption(STRING_KEY, "test"); + ApiCallContextOptions options2 = + ApiCallContextOptions.getDefaultOptions() + .withOption(STRING_KEY, "newTest") + .withOption(DOUBLE_KEY, 5.0); + ApiCallContextOptions mergedOptions = options1.merge(options2); + assertThat(mergedOptions.getOption(INTEGER_KEY)).isEqualTo(1); + assertThat(mergedOptions.getOption(STRING_KEY)).isEqualTo("newTest"); + assertThat(mergedOptions.getOption(DOUBLE_KEY)).isEqualTo(5.0); + } +}