Skip to content

Commit 745269d

Browse files
committed
gax: add ClientContext.createWithTransport
1 parent a4a47da commit 745269d

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

‎sdk-platform-java/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java‎

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.google.api.client.util.Strings;
3636
import com.google.api.core.ApiClock;
3737
import com.google.api.core.BetaApi;
38+
import com.google.api.core.InternalApi;
3839
import com.google.api.core.NanoClock;
3940
import com.google.api.core.ObsoleteApi;
4041
import com.google.api.gax.core.BackgroundResource;
@@ -292,6 +293,80 @@ public static ClientContext create(StubSettings settings) throws IOException {
292293
.build();
293294
}
294295

296+
/**
297+
* Derives a {@link ClientContext} for a second transport from {@code parent}, replacing the
298+
* transport channel, endpoint and internal headers and inheriting everything else.
299+
*/
300+
@InternalApi
301+
public static ClientContext createWithTransport(
302+
ClientContext parent,
303+
String endpoint,
304+
TransportChannelProvider transportChannelProvider,
305+
HeaderProvider internalHeaderProvider)
306+
throws IOException {
307+
Credentials credentials = parent.getCredentials();
308+
EndpointContext endpointContext = parent.getEndpointContext();
309+
310+
Map<String, String> internal = internalHeaderProvider.getHeaders();
311+
Map<String, String> user = parent.getHeaders();
312+
Map<String, String> conflictResolution = new HashMap<>();
313+
314+
for (String key : Sets.intersection(user.keySet(), internal.keySet())) {
315+
if ("user-agent".equals(key)) {
316+
conflictResolution.put(key, user.get(key) + " " + internal.get(key));
317+
continue;
318+
}
319+
if (QUOTA_PROJECT_ID_HEADER_KEY.equals(key) && parent.getQuotaProjectId() != null) {
320+
continue;
321+
}
322+
throw new IllegalArgumentException("Header provider can't override the header: " + key);
323+
}
324+
if (parent.getQuotaProjectId() != null) {
325+
conflictResolution.put(QUOTA_PROJECT_ID_HEADER_KEY, parent.getQuotaProjectId());
326+
}
327+
328+
Map<String, String> effective = new HashMap<>();
329+
effective.putAll(internal);
330+
effective.putAll(user);
331+
effective.putAll(conflictResolution);
332+
Map<String, String> headers = appendCredentialTypeToHeaderIfPresent(effective, credentials);
333+
334+
TransportChannelProvider provider = transportChannelProvider;
335+
if (provider.needsHeaders()) {
336+
provider = provider.withHeaders(headers);
337+
}
338+
if (provider.needsCredentials() && credentials != null) {
339+
provider = provider.withCredentials(credentials);
340+
}
341+
if (provider.needsEndpoint()) {
342+
provider = provider.withEndpoint(endpoint);
343+
}
344+
provider = provider.withUseS2A(endpointContext.useS2A());
345+
if (provider.needsMtlsEndpoint() && endpointContext.mtlsEndpoint() != null) {
346+
provider = provider.withMtlsEndpoint(endpointContext.mtlsEndpoint());
347+
}
348+
TransportChannel channel = provider.getTransportChannel();
349+
350+
ApiCallContext defaultCallContext = channel.getEmptyCallContext().withTransportChannel(channel);
351+
if (credentials != null) {
352+
defaultCallContext = defaultCallContext.withCredentials(credentials);
353+
}
354+
defaultCallContext = defaultCallContext.withEndpointContext(endpointContext);
355+
356+
ImmutableList.Builder<BackgroundResource> backgroundResources = ImmutableList.builder();
357+
if (provider.shouldAutoClose()) {
358+
backgroundResources.add(channel);
359+
}
360+
361+
return parent.toBuilder()
362+
.setEndpoint(endpoint)
363+
.setTransportChannel(channel)
364+
.setInternalHeaders(ImmutableMap.copyOf(internal))
365+
.setDefaultCallContext(defaultCallContext)
366+
.setBackgroundResources(backgroundResources.build())
367+
.build();
368+
}
369+
295370
@VisibleForTesting
296371
static ApiTracerFactory getApiTracerFactory(
297372
StubSettings settings, EndpointContext endpointContext) {

0 commit comments

Comments
 (0)