@@ -141,6 +141,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP
141
141
@ Nullable private final Boolean keepAliveWithoutCalls ;
142
142
private final ChannelPoolSettings channelPoolSettings ;
143
143
@ Nullable private final Credentials credentials ;
144
+ @ Nullable private final CallCredentials altsCallCredentials ;
144
145
@ Nullable private final CallCredentials mtlsS2ACallCredentials ;
145
146
@ Nullable private final ChannelPrimer channelPrimer ;
146
147
@ Nullable private final Boolean attemptDirectPath ;
@@ -191,6 +192,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) {
191
192
this .channelPoolSettings = builder .channelPoolSettings ;
192
193
this .channelConfigurator = builder .channelConfigurator ;
193
194
this .credentials = builder .credentials ;
195
+ this .altsCallCredentials = builder .altsCallCredentials ;
194
196
this .mtlsS2ACallCredentials = builder .mtlsS2ACallCredentials ;
195
197
this .channelPrimer = builder .channelPrimer ;
196
198
this .attemptDirectPath = builder .attemptDirectPath ;
@@ -616,8 +618,14 @@ private ManagedChannel createSingleChannel() throws IOException {
616
618
boolean useDirectPathXds = false ;
617
619
if (canUseDirectPath ()) {
618
620
CallCredentials callCreds = MoreCallCredentials .from (credentials );
621
+ // altsCallCredentials may be null and GoogleDefaultChannelCredentials
622
+ // will solely use callCreds. Otherwise it uses altsCallCredentials
623
+ // for DirectPath connections and callCreds for CloudPath fallbacks.
619
624
ChannelCredentials channelCreds =
620
- GoogleDefaultChannelCredentials .newBuilder ().callCredentials (callCreds ).build ();
625
+ GoogleDefaultChannelCredentials .newBuilder ()
626
+ .callCredentials (callCreds )
627
+ .altsCallCredentials (altsCallCredentials )
628
+ .build ();
621
629
useDirectPathXds = isDirectPathXdsEnabled ();
622
630
if (useDirectPathXds ) {
623
631
// google-c2p: CloudToProd(C2P) Directpath. This scheme is defined in
@@ -822,6 +830,7 @@ public static final class Builder {
822
830
@ Nullable private Boolean keepAliveWithoutCalls ;
823
831
@ Nullable private ApiFunction <ManagedChannelBuilder , ManagedChannelBuilder > channelConfigurator ;
824
832
@ Nullable private Credentials credentials ;
833
+ @ Nullable private CallCredentials altsCallCredentials ;
825
834
@ Nullable private CallCredentials mtlsS2ACallCredentials ;
826
835
@ Nullable private ChannelPrimer channelPrimer ;
827
836
private ChannelPoolSettings channelPoolSettings ;
@@ -853,6 +862,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) {
853
862
this .keepAliveWithoutCalls = provider .keepAliveWithoutCalls ;
854
863
this .channelConfigurator = provider .channelConfigurator ;
855
864
this .credentials = provider .credentials ;
865
+ this .altsCallCredentials = provider .altsCallCredentials ;
856
866
this .mtlsS2ACallCredentials = provider .mtlsS2ACallCredentials ;
857
867
this .channelPrimer = provider .channelPrimer ;
858
868
this .channelPoolSettings = provider .channelPoolSettings ;
@@ -919,6 +929,7 @@ Builder setUseS2A(boolean useS2A) {
919
929
this .useS2A = useS2A ;
920
930
return this ;
921
931
}
932
+
922
933
/*
923
934
* Sets the allowed hard bound token types for this TransportChannelProvider.
924
935
*
@@ -996,6 +1007,7 @@ public Integer getMaxInboundMetadataSize() {
996
1007
public Builder setKeepAliveTime (org .threeten .bp .Duration duration ) {
997
1008
return setKeepAliveTimeDuration (toJavaTimeDuration (duration ));
998
1009
}
1010
+
999
1011
/** The time without read activity before sending a keepalive ping. */
1000
1012
public Builder setKeepAliveTimeDuration (java .time .Duration duration ) {
1001
1013
this .keepAliveTime = duration ;
@@ -1172,6 +1184,18 @@ boolean isMtlsS2AHardBoundTokensEnabled() {
1172
1184
.anyMatch (val -> val .equals (HardBoundTokenTypes .MTLS_S2A ));
1173
1185
}
1174
1186
1187
+ boolean isDirectPathBoundTokenEnabled () {
1188
+ // If the list of allowed hard bound token types is empty or doesn't contain
1189
+ // {@code HardBoundTokenTypes.ALTS}, the {@code credentials} are null or not of type
1190
+ // {@code ComputeEngineCredentials} then DirectPath hard bound tokens should not be used.
1191
+ // DirectPath hard bound tokens should only be used on ALTS channels.
1192
+ if (allowedHardBoundTokenTypes .isEmpty ()
1193
+ || this .credentials == null
1194
+ || !(credentials instanceof ComputeEngineCredentials )) return false ;
1195
+ return allowedHardBoundTokenTypes .stream ()
1196
+ .anyMatch (val -> val .equals (HardBoundTokenTypes .ALTS ));
1197
+ }
1198
+
1175
1199
CallCredentials createHardBoundTokensCallCredentials (
1176
1200
ComputeEngineCredentials .GoogleAuthTransport googleAuthTransport ,
1177
1201
ComputeEngineCredentials .BindingEnforcement bindingEnforcement ) {
@@ -1194,6 +1218,11 @@ public InstantiatingGrpcChannelProvider build() {
1194
1218
ComputeEngineCredentials .GoogleAuthTransport .MTLS ,
1195
1219
ComputeEngineCredentials .BindingEnforcement .ON );
1196
1220
}
1221
+ if (isDirectPathBoundTokenEnabled ()) {
1222
+ this .altsCallCredentials =
1223
+ createHardBoundTokensCallCredentials (
1224
+ ComputeEngineCredentials .GoogleAuthTransport .ALTS , null );
1225
+ }
1197
1226
InstantiatingGrpcChannelProvider instantiatingGrpcChannelProvider =
1198
1227
new InstantiatingGrpcChannelProvider (this );
1199
1228
instantiatingGrpcChannelProvider .removeApiKeyCredentialDuplicateHeaders ();
0 commit comments