Skip to content

Commit 597f501

Browse files
authored
fix: check if emulator is running if env var is set (#340)
* fix: check if emulator is running if env var is set * fix: only test for emulator if no channel provider is set
1 parent 60dd9fb commit 597f501

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java

+50
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@
4242
import com.google.api.gax.rpc.StatusCode;
4343
import com.google.api.gax.rpc.StreamController;
4444
import com.google.api.gax.rpc.TransportChannelProvider;
45+
import com.google.api.gax.rpc.UnavailableException;
4546
import com.google.api.gax.rpc.WatchdogProvider;
4647
import com.google.api.pathtemplate.PathTemplate;
4748
import com.google.cloud.RetryHelper;
4849
import com.google.cloud.grpc.GrpcTransportOptions;
50+
import com.google.cloud.spanner.ErrorCode;
4951
import com.google.cloud.spanner.SpannerException;
5052
import com.google.cloud.spanner.SpannerExceptionFactory;
5153
import com.google.cloud.spanner.SpannerOptions;
@@ -55,6 +57,7 @@
5557
import com.google.cloud.spanner.admin.database.v1.stub.GrpcDatabaseAdminStub;
5658
import com.google.cloud.spanner.admin.instance.v1.stub.GrpcInstanceAdminStub;
5759
import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStub;
60+
import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStubSettings;
5861
import com.google.cloud.spanner.spi.v1.SpannerRpc.Option;
5962
import com.google.cloud.spanner.v1.stub.GrpcSpannerStub;
6063
import com.google.cloud.spanner.v1.stub.SpannerStub;
@@ -136,6 +139,7 @@
136139
import com.google.spanner.v1.Transaction;
137140
import io.grpc.CallCredentials;
138141
import io.grpc.Context;
142+
import java.io.IOException;
139143
import java.io.UnsupportedEncodingException;
140144
import java.net.URLDecoder;
141145
import java.nio.charset.StandardCharsets;
@@ -401,11 +405,57 @@ public GapicSpannerRpc(final SpannerOptions options) {
401405
.setStreamWatchdogProvider(watchdogProvider)
402406
.build();
403407
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);
404412
} catch (Exception e) {
405413
throw newSpannerException(e);
406414
}
407415
}
408416

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+
409459
private static final class OperationFutureRetryAlgorithm<ResultT, MetadataT>
410460
implements ResultRetryAlgorithm<OperationFuture<ResultT, MetadataT>> {
411461
private static final ImmutableList<StatusCode.Code> RETRYABLE_CODES =

0 commit comments

Comments
 (0)