3434import java .io .InputStreamReader ;
3535import java .net .ServerSocket ;
3636import java .net .Socket ;
37+ import java .nio .file .Files ;
38+ import java .nio .file .Path ;
3739import java .nio .file .Paths ;
3840import java .util .concurrent .Callable ;
41+ import java .util .concurrent .ExecutionException ;
3942import java .util .concurrent .Future ;
4043import java .util .concurrent .FutureTask ;
4144import java .util .concurrent .TimeUnit ;
4952class Emulator {
5053 private static final Logger LOGGER = Logger .getLogger (Emulator .class .getName ());
5154
52- private final String executable ;
55+ private final Path executable ;
5356 private Process process ;
5457 private ManagedChannel channel ;
5558 private BigtableTableAdminClient tableAdminClient ;
@@ -58,47 +61,32 @@ class Emulator {
5861 private static final InstanceName INSTANCE_NAME =
5962 InstanceName .of ("fake-project" , "fake-instance" );
6063
64+ // Use the gcloud installed emulator
6165 static Emulator createGCloud () {
62- final Process p ;
66+ final Path gcloudSdkPath ;
6367
6468 try {
65- p = Runtime .getRuntime ().exec ("gcloud info --format=value(installation.sdk_root)" );
66- pipeStreamToLog (p .getErrorStream (), Level .WARNING );
67- } catch (IOException e ) {
68- throw new RuntimeException ("Failed to run gcloud info" , e );
69- }
70-
71- String sdkRoot ;
72- try {
73- sdkRoot = bufferOutput (p .getInputStream ()).get (1 , TimeUnit .MINUTES ).trim ();
69+ gcloudSdkPath = getGcloudSdkPath ();
7470 } catch (Exception e ) {
75- throw new RuntimeException ("Failed to get gcloud sdk install path" , e );
76- }
77-
78- try {
79- if (p .waitFor () != 0 ) {
80- throw new RuntimeException ("Failed to get sdk root, is gcloud sdk installed?" );
81- }
82- } catch (InterruptedException e ) {
83- throw new RuntimeException ("Interrupted invoking gcloud" , e );
71+ throw new RuntimeException ("Failed to get the gcloud SDK path. Is it installed?" , e );
8472 }
8573
86- String emulatorPath =
87- Paths .get (sdkRoot , "platform" , "bigtable-emulator" , "cbtemulator" ). toString ( );
74+ Path emulatorPath =
75+ gcloudSdkPath . resolve ( Paths .get ("platform" , "bigtable-emulator" , "cbtemulator" ));
8876
89- if (!new File ( emulatorPath ) .exists ()) {
77+ if (!Files .exists (emulatorPath )) {
9078 throw new RuntimeException (
9179 "cbtemulator is not installed, please install with `gcloud components install bigtable`" );
9280 }
9381
9482 return new Emulator (emulatorPath );
9583 }
9684
97- private Emulator (String executable ) {
85+ private Emulator (Path executable ) {
9886 this .executable = executable ;
9987 }
10088
101- void start () throws InterruptedException , IOException , TimeoutException {
89+ void start () throws Exception {
10290 int availablePort = getAvailablePort ();
10391
10492 process = Runtime .getRuntime ().exec (executable + " -port " + "" + availablePort );
@@ -120,11 +108,14 @@ void start() throws InterruptedException, IOException, TimeoutException {
120108 }
121109
122110 void stop () throws Exception {
123- dataClient .close ();
124- tableAdminClient .close ();
125- channel .shutdownNow ();
126- channel .awaitTermination (1 , TimeUnit .MINUTES );
127- process .destroy ();
111+ try {
112+ dataClient .close ();
113+ tableAdminClient .close ();
114+ channel .shutdownNow ();
115+ channel .awaitTermination (1 , TimeUnit .MINUTES );
116+ } finally {
117+ process .destroy ();
118+ }
128119 }
129120
130121 BigtableDataClient getDataClient () {
@@ -136,6 +127,18 @@ BigtableTableAdminClient getTableAdminClient() {
136127 }
137128
138129 // <editor-fold desc="Helpers">
130+ private static Path getGcloudSdkPath () throws Exception {
131+ Process p = Runtime .getRuntime ().exec ("gcloud info --format=value(installation.sdk_root)" );
132+ pipeStreamToLog (p .getErrorStream (), Level .WARNING );
133+
134+ String sdkRoot = bufferOutput (p .getInputStream ()).get (1 , TimeUnit .MINUTES ).trim ();
135+
136+ if (p .waitFor () != 0 ) {
137+ throw new RuntimeException ("Failed to get sdk root, is gcloud sdk installed?" );
138+ }
139+ return Paths .get (sdkRoot );
140+ }
141+
139142 private static int getAvailablePort () {
140143 try (ServerSocket serverSocket = new ServerSocket (0 )) {
141144 return serverSocket .getLocalPort ();
0 commit comments