4444import com .google .common .base .Preconditions ;
4545import com .google .common .collect .ImmutableList ;
4646import com .google .common .collect .ImmutableMap ;
47+ import com .google .common .io .CharStreams ;
4748import io .grpc .ManagedChannel ;
4849import io .grpc .ManagedChannelBuilder ;
4950import io .grpc .alts .ComputeEngineChannelBuilder ;
5051import java .io .IOException ;
52+ import java .io .InputStreamReader ;
5153import java .util .Map ;
5254import java .util .concurrent .Executor ;
5355import java .util .concurrent .ScheduledExecutorService ;
@@ -74,6 +76,8 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP
7476 static final long DIRECT_PATH_KEEP_ALIVE_TIMEOUT_SECONDS = 20 ;
7577 // reduce the thundering herd problem of too many channels trying to (re)connect at the same time
7678 static final int MAX_POOL_SIZE = 1000 ;
79+ static final String GCE_PRODUCTION_NAME_PRIOR_2016 = "Google" ;
80+ static final String GCE_PRODUCTION_NAME_AFTER_2016 = "Google Compute Engine" ;
7781
7882 private final int processorCount ;
7983 private final Executor executor ;
@@ -234,6 +238,26 @@ private boolean isDirectPathEnabled(String serviceAddress) {
234238 return false ;
235239 }
236240
241+ // DirectPath should only be used on Compute Engine.
242+ // Notice Windows is supported for now.
243+ static boolean isOnComputeEngine () {
244+ String osName = System .getProperty ("os.name" );
245+ if ("Linux" .equals (osName )) {
246+ String cmd = "cat /sys/class/dmi/id/product_name" ;
247+ try {
248+ Process process = Runtime .getRuntime ().exec (new String [] {"/bin/sh" , "-c" , cmd });
249+ process .waitFor ();
250+ String result =
251+ CharStreams .toString (new InputStreamReader (process .getInputStream (), "UTF-8" ));
252+ return result .contains (GCE_PRODUCTION_NAME_PRIOR_2016 )
253+ || result .contains (GCE_PRODUCTION_NAME_AFTER_2016 );
254+ } catch (IOException | InterruptedException e ) {
255+ return false ;
256+ }
257+ }
258+ return false ;
259+ }
260+
237261 private ManagedChannel createSingleChannel () throws IOException {
238262 GrpcHeaderInterceptor headerInterceptor =
239263 new GrpcHeaderInterceptor (headerProvider .getHeaders ());
@@ -250,7 +274,9 @@ private ManagedChannel createSingleChannel() throws IOException {
250274 ManagedChannelBuilder builder ;
251275
252276 // TODO(weiranf): Add API in ComputeEngineCredentials to check default service account.
253- if (isDirectPathEnabled (serviceAddress ) && credentials instanceof ComputeEngineCredentials ) {
277+ if (isDirectPathEnabled (serviceAddress )
278+ && credentials instanceof ComputeEngineCredentials
279+ && isOnComputeEngine ()) {
254280 builder = ComputeEngineChannelBuilder .forAddress (serviceAddress , port );
255281 // Set default keepAliveTime and keepAliveTimeout when directpath environment is enabled.
256282 // Will be overridden by user defined values if any.
0 commit comments