1717package com .google .cloud .spanner .connection ;
1818
1919import com .google .api .core .InternalApi ;
20- import com .google .api .gax .core .NoCredentialsProvider ;
21- import com .google .api .gax .grpc .InstantiatingGrpcChannelProvider ;
22- import com .google .api .gax .rpc .UnavailableException ;
23- import com .google .api .gax .rpc .UnimplementedException ;
2420import com .google .auth .Credentials ;
2521import com .google .auth .oauth2 .AccessToken ;
2622import com .google .auth .oauth2 .GoogleCredentials ;
3430import com .google .cloud .spanner .SpannerException ;
3531import com .google .cloud .spanner .SpannerExceptionFactory ;
3632import com .google .cloud .spanner .SpannerOptions ;
37- import com .google .cloud .spanner .admin .instance .v1 .stub .GrpcInstanceAdminStub ;
38- import com .google .cloud .spanner .admin .instance .v1 .stub .InstanceAdminStubSettings ;
3933import com .google .common .annotations .VisibleForTesting ;
4034import com .google .common .base .Preconditions ;
4135import com .google .common .collect .Sets ;
42- import com .google .spanner .admin .instance .v1 .ListInstanceConfigsRequest ;
4336import com .google .spanner .v1 .ExecuteSqlRequest .QueryOptions ;
44- import java .io .IOException ;
4537import java .util .ArrayList ;
4638import java .util .Arrays ;
4739import java .util .Collections ;
5143import java .util .regex .Matcher ;
5244import java .util .regex .Pattern ;
5345import javax .annotation .Nullable ;
54- import org .threeten .bp .Duration ;
5546
5647/**
5748 * Internal connection API for Google Cloud Spanner. This class may introduce breaking changes
@@ -153,6 +144,8 @@ public String[] getValidValues() {
153144 }
154145 }
155146
147+ private static final LocalConnectionChecker LOCAL_CONNECTION_CHECKER =
148+ new LocalConnectionChecker ();
156149 private static final boolean DEFAULT_USE_PLAIN_TEXT = false ;
157150 static final boolean DEFAULT_AUTOCOMMIT = true ;
158151 static final boolean DEFAULT_READONLY = false ;
@@ -740,65 +733,6 @@ static List<String> parseProperties(String uri) {
740733 return res ;
741734 }
742735
743- /**
744- * Executes a quick check to see if this connection can actually connect to a local emulator host
745- * or other (mock) test server, if the options point to localhost instead of Cloud Spanner.
746- */
747- private void checkLocalConnection () {
748- final String emulatorHost = System .getenv ("SPANNER_EMULATOR_HOST" );
749- String host = getHost () == null ? emulatorHost : getHost ();
750- if (host .startsWith ("https://" )) {
751- host = host .substring (8 );
752- }
753- if (host .startsWith ("http://" )) {
754- host = host .substring (7 );
755- }
756- // Only do the check if the host has been set to localhost.
757- if (host != null && host .startsWith ("localhost" ) && isUsePlainText ()) {
758- // Do a quick check to see if anything is actually running on the host.
759- try {
760- InstanceAdminStubSettings .Builder testEmulatorSettings =
761- InstanceAdminStubSettings .newBuilder ()
762- .setCredentialsProvider (NoCredentialsProvider .create ())
763- .setTransportChannelProvider (
764- InstantiatingGrpcChannelProvider .newBuilder ().setEndpoint (host ).build ());
765- testEmulatorSettings
766- .listInstanceConfigsSettings ()
767- .setSimpleTimeoutNoRetries (Duration .ofSeconds (10L ));
768- try (GrpcInstanceAdminStub stub =
769- GrpcInstanceAdminStub .create (testEmulatorSettings .build ())) {
770- stub .listInstanceConfigsCallable ()
771- .call (
772- ListInstanceConfigsRequest .newBuilder ()
773- .setParent (String .format ("projects/%s" , getProjectId ()))
774- .build ());
775- }
776- } catch (UnavailableException e ) {
777- String msg ;
778- if (getHost () != null ) {
779- msg =
780- String .format (
781- "The connection string '%s' contains host '%s', but no running"
782- + " emulator or other server could be found at that address.\n "
783- + "Please check the connection string and/or that the emulator is running." ,
784- getUri (), host );
785- } else {
786- msg =
787- String .format (
788- "The environment variable SPANNER_EMULATOR_HOST has been set to '%s', but no running"
789- + " emulator or other server could be found at that address.\n "
790- + "Please check the environment variable and/or that the emulator is running." ,
791- emulatorHost );
792- }
793- throw SpannerExceptionFactory .newSpannerException (ErrorCode .UNAVAILABLE , msg );
794- } catch (UnimplementedException e ) {
795- // Ignore, this is probably a local mock server.
796- } catch (IOException e ) {
797- // Ignore, this method is not checking whether valid credentials have been set.
798- }
799- }
800- }
801-
802736 /**
803737 * Create a new {@link Connection} from this {@link ConnectionOptions}. Calling this method
804738 * multiple times for the same {@link ConnectionOptions} will return multiple instances of {@link
@@ -807,7 +741,7 @@ private void checkLocalConnection() {
807741 * @return a new {@link Connection} to the database referenced by this {@link ConnectionOptions}
808742 */
809743 public Connection getConnection () {
810- checkLocalConnection ();
744+ LOCAL_CONNECTION_CHECKER . checkLocalConnection (this );
811745 return new ConnectionImpl (this );
812746 }
813747
0 commit comments