|
42 | 42 | import com.google.api.gax.rpc.StatusCode;
|
43 | 43 | import com.google.api.gax.rpc.StreamController;
|
44 | 44 | import com.google.api.gax.rpc.TransportChannelProvider;
|
| 45 | +import com.google.api.gax.rpc.UnavailableException; |
45 | 46 | import com.google.api.gax.rpc.WatchdogProvider;
|
46 | 47 | import com.google.api.pathtemplate.PathTemplate;
|
47 | 48 | import com.google.cloud.RetryHelper;
|
48 | 49 | import com.google.cloud.grpc.GrpcTransportOptions;
|
| 50 | +import com.google.cloud.spanner.ErrorCode; |
49 | 51 | import com.google.cloud.spanner.SpannerException;
|
50 | 52 | import com.google.cloud.spanner.SpannerExceptionFactory;
|
51 | 53 | import com.google.cloud.spanner.SpannerOptions;
|
|
55 | 57 | import com.google.cloud.spanner.admin.database.v1.stub.GrpcDatabaseAdminStub;
|
56 | 58 | import com.google.cloud.spanner.admin.instance.v1.stub.GrpcInstanceAdminStub;
|
57 | 59 | import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStub;
|
| 60 | +import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStubSettings; |
58 | 61 | import com.google.cloud.spanner.spi.v1.SpannerRpc.Option;
|
59 | 62 | import com.google.cloud.spanner.v1.stub.GrpcSpannerStub;
|
60 | 63 | import com.google.cloud.spanner.v1.stub.SpannerStub;
|
|
136 | 139 | import com.google.spanner.v1.Transaction;
|
137 | 140 | import io.grpc.CallCredentials;
|
138 | 141 | import io.grpc.Context;
|
| 142 | +import java.io.IOException; |
139 | 143 | import java.io.UnsupportedEncodingException;
|
140 | 144 | import java.net.URLDecoder;
|
141 | 145 | import java.nio.charset.StandardCharsets;
|
@@ -401,11 +405,57 @@ public GapicSpannerRpc(final SpannerOptions options) {
|
401 | 405 | .setStreamWatchdogProvider(watchdogProvider)
|
402 | 406 | .build();
|
403 | 407 | this.databaseAdminStub = GrpcDatabaseAdminStub.create(this.databaseAdminStubSettings);
|
| 408 | + |
| 409 | + // Check whether the SPANNER_EMULATOR_HOST env var has been set, and if so, if the emulator is |
| 410 | + // actually running. |
| 411 | + checkEmulatorConnection(options, channelProvider, credentialsProvider); |
404 | 412 | } catch (Exception e) {
|
405 | 413 | throw newSpannerException(e);
|
406 | 414 | }
|
407 | 415 | }
|
408 | 416 |
|
| 417 | + private static void checkEmulatorConnection( |
| 418 | + SpannerOptions options, |
| 419 | + TransportChannelProvider channelProvider, |
| 420 | + CredentialsProvider credentialsProvider) |
| 421 | + throws IOException { |
| 422 | + final String emulatorHost = System.getenv("SPANNER_EMULATOR_HOST"); |
| 423 | + // Only do the check if the emulator environment variable has been set to localhost. |
| 424 | + if (options.getChannelProvider() == null |
| 425 | + && emulatorHost != null |
| 426 | + && options.getHost() != null |
| 427 | + && options.getHost().startsWith("http://localhost") |
| 428 | + && options.getHost().endsWith(emulatorHost)) { |
| 429 | + // Do a quick check to see if the emulator is actually running. |
| 430 | + try { |
| 431 | + InstanceAdminStubSettings.Builder testEmulatorSettings = |
| 432 | + options |
| 433 | + .getInstanceAdminStubSettings() |
| 434 | + .toBuilder() |
| 435 | + .setTransportChannelProvider(channelProvider) |
| 436 | + .setCredentialsProvider(credentialsProvider); |
| 437 | + testEmulatorSettings |
| 438 | + .listInstanceConfigsSettings() |
| 439 | + .setSimpleTimeoutNoRetries(Duration.ofSeconds(10L)); |
| 440 | + try (GrpcInstanceAdminStub stub = |
| 441 | + GrpcInstanceAdminStub.create(testEmulatorSettings.build())) { |
| 442 | + stub.listInstanceConfigsCallable() |
| 443 | + .call( |
| 444 | + ListInstanceConfigsRequest.newBuilder() |
| 445 | + .setParent(String.format("projects/%s", options.getProjectId())) |
| 446 | + .build()); |
| 447 | + } |
| 448 | + } catch (UnavailableException e) { |
| 449 | + throw SpannerExceptionFactory.newSpannerException( |
| 450 | + ErrorCode.UNAVAILABLE, |
| 451 | + String.format( |
| 452 | + "The environment variable SPANNER_EMULATOR_HOST has been set to %s, but no running emulator could be found at that address.\n" |
| 453 | + + "Did you forget to start the emulator, or to unset the environment variable?", |
| 454 | + emulatorHost)); |
| 455 | + } |
| 456 | + } |
| 457 | + } |
| 458 | + |
409 | 459 | private static final class OperationFutureRetryAlgorithm<ResultT, MetadataT>
|
410 | 460 | implements ResultRetryAlgorithm<OperationFuture<ResultT, MetadataT>> {
|
411 | 461 | private static final ImmutableList<StatusCode.Code> RETRYABLE_CODES =
|
|
0 commit comments