Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix: remove call credentials from call options if DirectPath#3670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lqiu96 merged 13 commits intogoogleapis:mainfromrockspore:grpc-creds-alt
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
13 commits
Select commitHold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -96,6 +96,7 @@ public final class GrpcCallContext implements ApiCallContext {
private final ImmutableMap<String, List<String>> extraHeaders;
private final ApiCallContextOptions options;
private final EndpointContext endpointContext;
private final boolean isDirectPath;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

There wasan issue reported thatisDirectPath may not be correct populated in some cases.@lqiu96 is looking into it.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks for the info. I thought that referred tocanUseDirectPath() which could be invoked multiple times before and after the credentials was set so might be no accurate, but by the time the ClientContext got this boolean from the channel, it should already be final.

Copy link
Member

@lqiu96lqiu96Mar 7, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Talked with@surbhigarg92 regarding this to get some more information about the issue. This issue from Spanner's POV is not so much that thecanUseDirectPath value that is client is initialized with and used by the TransportChannel is incorrect, it's that Spanner doesn't have a way to get thecanUseDirectPath value when initializing the client for Otel.

Spanner was usingGrpcSpannerStub.create(StubSettings) and didn't have an easy way to access to TransportChannel's fields (StubSettings only exposesgetTransportChannelProvider(). Spanner could useGrpcSpannerStub.create(ClientContext), but that creates the Stub with a new StubSettings and not the one they manually configured.

For them, the DirectPath transportchannel was always created correctly and the value the client uses is correct. They used this workaround to be able to access the field for their use case.

I think their issue is a valid concern, but is different from this.

rockspore and blakeli0 reacted with thumbs up emoji

/** Returns an empty instance with a null channel and default {@link CallOptions}. */
public static GrpcCallContext createDefault() {
Expand All@@ -111,7 +112,8 @@ public static GrpcCallContext createDefault() {
ApiCallContextOptions.getDefaultOptions(),
null,
null,
null);
null,
false);
}

/** Returns an instance with the given channel and {@link CallOptions}. */
Expand All@@ -128,7 +130,8 @@ public static GrpcCallContext of(Channel channel, CallOptions callOptions) {
ApiCallContextOptions.getDefaultOptions(),
null,
null,
null);
null,
false);
}

private GrpcCallContext(
Expand All@@ -143,10 +146,14 @@ private GrpcCallContext(
ApiCallContextOptions options,
@Nullable RetrySettings retrySettings,
@Nullable Set<StatusCode.Code> retryableCodes,
@Nullable EndpointContext endpointContext) {
@Nullable EndpointContext endpointContext,
boolean isDirectPath) {
this.channel = channel;
this.credentials = credentials;
this.callOptions = Preconditions.checkNotNull(callOptions);
Preconditions.checkNotNull(callOptions);
// CallCredentials is stripped from CallOptions because CallCredentials are attached
// to ChannelCredentials in DirectPath flows. Adding it again would duplicate the headers.
this.callOptions = isDirectPath ? callOptions.withCallCredentials(null) : callOptions;
this.timeout = timeout;
this.streamWaitTimeout = streamWaitTimeout;
this.streamIdleTimeout = streamIdleTimeout;
Expand All@@ -159,6 +166,7 @@ private GrpcCallContext(
// a valid EndpointContext with user configurations after the client has been initialized.
this.endpointContext =
endpointContext == null ? EndpointContext.getDefaultInstance() : endpointContext;
this.isDirectPath = isDirectPath;
}

/**
Expand DownExpand Up@@ -199,7 +207,8 @@ public GrpcCallContext withCredentials(Credentials newCredentials) {
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

@Override
Expand All@@ -210,7 +219,20 @@ public GrpcCallContext withTransportChannel(TransportChannel inputChannel) {
"Expected GrpcTransportChannel, got " + inputChannel.getClass().getName());
}
GrpcTransportChannel transportChannel = (GrpcTransportChannel) inputChannel;
return withChannel(transportChannel.getChannel());
return new GrpcCallContext(
transportChannel.getChannel(),
credentials,
callOptions,
timeout,
streamWaitTimeout,
streamIdleTimeout,
channelAffinity,
extraHeaders,
options,
retrySettings,
retryableCodes,
endpointContext,
transportChannel.isDirectPath());
}

@Override
Expand All@@ -228,7 +250,8 @@ public GrpcCallContext withEndpointContext(EndpointContext endpointContext) {
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Its unfortunate that we have to change all the places that use the constructor. Ideally, if we had a builder forGrpcCallContext, the code here would be simplified tothis.toBuilder().setEndpointContext(endpointContext).build(), and we don't have to change the code here at all.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Agreed. But I'd prefer to leave the refactoring with a builder out of this PR since it would look cleaner. I can open an issue for it. Let me know what you think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

SG. Yes please create a separate issue and we can put it in our backlog.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks. Created#3681

isDirectPath);
}

/** This method is obsolete. Use {@link #withTimeoutDuration(java.time.Duration)} instead. */
Expand DownExpand Up@@ -262,7 +285,8 @@ public GrpcCallContext withTimeoutDuration(@Nullable java.time.Duration timeout)
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

/** This method is obsolete. Use {@link #getTimeoutDuration()} instead. */
Expand DownExpand Up@@ -310,7 +334,8 @@ public GrpcCallContext withStreamWaitTimeoutDuration(
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

/**
Expand DownExpand Up@@ -344,7 +369,8 @@ public GrpcCallContext withStreamIdleTimeoutDuration(
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

@BetaApi("The surface for channel affinity is not stable yet and may change in the future.")
Expand All@@ -361,7 +387,8 @@ public GrpcCallContext withChannelAffinity(@Nullable Integer affinity) {
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

@BetaApi("The surface for extra headers is not stable yet and may change in the future.")
Expand All@@ -382,7 +409,8 @@ public GrpcCallContext withExtraHeaders(Map<String, List<String>> extraHeaders)
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

@Override
Expand All@@ -404,7 +432,8 @@ public GrpcCallContext withRetrySettings(RetrySettings retrySettings) {
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

@Override
Expand All@@ -426,7 +455,8 @@ public GrpcCallContext withRetryableCodes(Set<StatusCode.Code> retryableCodes) {
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

@Override
Expand DownExpand Up@@ -456,6 +486,8 @@ public ApiCallContext merge(ApiCallContext inputCallContext) {
newDeadline = callOptions.getDeadline();
}

boolean newIsDirectPath = grpcCallContext.isDirectPath;

CallCredentials newCallCredentials = grpcCallContext.callOptions.getCredentials();
if (newCallCredentials == null) {
newCallCredentials = callOptions.getCredentials();
Expand DownExpand Up@@ -525,7 +557,8 @@ public ApiCallContext merge(ApiCallContext inputCallContext) {
newOptions,
newRetrySettings,
newRetryableCodes,
endpointContext);
endpointContext,
newIsDirectPath);
}

/** The {@link Channel} set on this context. */
Expand DownExpand Up@@ -588,7 +621,11 @@ public Map<String, List<String>> getExtraHeaders() {
return extraHeaders;
}

/** Returns a new instance with the channel set to the given channel. */
/**
* This method is obsolete. Use {@link #withTransportChannel()} instead. Returns a new instance
* with the channel set to the given channel.
*/
@ObsoleteApi("Use withTransportChannel() instead")
public GrpcCallContext withChannel(Channel newChannel) {
return new GrpcCallContext(
newChannel,
Expand All@@ -602,7 +639,8 @@ public GrpcCallContext withChannel(Channel newChannel) {
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

/** Returns a new instance with the call options set to the given call options. */
Expand All@@ -619,7 +657,8 @@ public GrpcCallContext withCallOptions(CallOptions newCallOptions) {
options,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

public GrpcCallContext withRequestParamsDynamicHeaderOption(String requestParams) {
Expand DownExpand Up@@ -663,7 +702,8 @@ public <T> GrpcCallContext withOption(Key<T> key, T value) {
newOptions,
retrySettings,
retryableCodes,
endpointContext);
endpointContext,
isDirectPath);
}

/** {@inheritDoc} */
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,14 @@
import com.google.api.gax.rpc.testing.FakeTransportChannel;
import com.google.api.gax.tracing.ApiTracer;
import com.google.auth.Credentials;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.collect.ImmutableMap;
import com.google.common.truth.Truth;
import io.grpc.CallCredentials;
import io.grpc.CallOptions;
import io.grpc.ManagedChannel;
import io.grpc.Metadata.Key;
import io.grpc.auth.MoreCallCredentials;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
Expand DownExpand Up@@ -100,6 +103,26 @@ void testWithTransportChannelWrongType() {
}
}

@Test
void testWithTransportChannelIsDirectPath() {
ManagedChannel channel = Mockito.mock(ManagedChannel.class);
Credentials credentials = Mockito.mock(GoogleCredentials.class);
GrpcCallContext context = GrpcCallContext.createDefault().withCredentials(credentials);
assertNotNull(context.getCallOptions().getCredentials());
context =
context.withTransportChannel(
GrpcTransportChannel.newBuilder()
.setDirectPath(true)
.setManagedChannel(channel)
.build());
assertNull(context.getCallOptions().getCredentials());

// Call credentials from the call options will be stripped.
context.withCallOptions(
CallOptions.DEFAULT.withCallCredentials(MoreCallCredentials.from(credentials)));
assertNull(context.getCallOptions().getCredentials());
}

@Test
void testMergeWrongType() {
try {
Expand DownExpand Up@@ -320,6 +343,25 @@ void testMergeWithCustomCallOptions() {
.isEqualTo(ctx2.getCallOptions().getOption(key));
}

@Test
void testMergeWithIsDirectPath() {
ManagedChannel channel = Mockito.mock(ManagedChannel.class);
CallCredentials callCredentials = Mockito.mock(CallCredentials.class);
GrpcCallContext ctx1 =
GrpcCallContext.createDefault()
.withCallOptions(CallOptions.DEFAULT.withCallCredentials(callCredentials));
GrpcCallContext ctx2 =
GrpcCallContext.createDefault()
.withTransportChannel(
GrpcTransportChannel.newBuilder()
.setDirectPath(true)
.setManagedChannel(channel)
.build());

GrpcCallContext merged = (GrpcCallContext) ctx1.merge(ctx2);
assertNull(merged.getCallOptions().getCredentials());
}

@Test
void testWithExtraHeaders() {
Map<String, List<String>> extraHeaders =
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp