3535 * A class that runs a Pubsub emulator instance for use in tests.
3636 */
3737public class LocalPubsubHelper {
38+
39+ private final int port ;
3840 private final LocalServiceHelper serviceHelper ;
39- private final List <String > gcloudCommand ;
40- private final URL emulatorUrl ;
4141
4242 // Local server settings
4343 private static final int DEFAULT_PORT = 8080 ;
4444 private static final String DEFAULT_HOST = "localhost" ;
45+ private static final URL EMULATOR_URL ;
4546
4647 // GCloud emulator settings
47- private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators pubsub start --host-port" ;
48+ private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators pubsub start" ;
49+ private static final String GCLOUD_CMD_PORT_FLAG = "--host-port=" ;
4850 private static final String VERSION_PREFIX = "pubsub-emulator" ;
4951 private static final String MIN_VERSION = "2016.01.13" ;
52+ private static final String BIN_CMD_PORT_FLAG = "--port=" ;
5053
5154 // Downloadable emulator settings
5255 private static final String FILENAME = "pubsub-emulator-20160113-2.zip" ;
5356 private static final String BIN_NAME = "pubsub-emulator/bin/cloud-pubsub-fake" ;
5457 private static final String MD5_CHECKSUM = "20943e9defa300f2de101568459c133d" ;
5558
59+ static {
60+ try {
61+ EMULATOR_URL = new URL ("http://storage.googleapis.com/pubsub/tools/" + FILENAME );
62+ } catch (MalformedURLException ex ) {
63+ throw new IllegalStateException (ex );
64+ }
65+ }
66+
5667 /**
5768 * Constructs a new LocalPubsubHelper. The method start() must
5869 * be called before it is used.
59- * @throws MalformedURLException
6070 */
61- public LocalPubsubHelper () throws MalformedURLException {
62- gcloudCommand = new ArrayList <>( Arrays . asList ( GCLOUD_CMD_TEXT . split ( " " )) );
63- gcloudCommand . add ( DEFAULT_HOST );
64- emulatorUrl = new URL ( "http://storage.googleapis.com/pubsub/tools/" + FILENAME );
71+ public LocalPubsubHelper () {
72+ port = LocalServiceHelper . findAvailablePort ( DEFAULT_PORT );
73+ List < String > gcloudCommand = new ArrayList <>( Arrays . asList ( GCLOUD_CMD_TEXT . split ( " " )) );
74+ gcloudCommand . add ( GCLOUD_CMD_PORT_FLAG + port );
6575 GCloudEmulatorRunner gcloudRunner =
6676 new GCloudEmulatorRunner (gcloudCommand , VERSION_PREFIX , MIN_VERSION );
6777 DownloadableEmulatorRunner downloadRunner =
68- new DownloadableEmulatorRunner (Arrays .asList (BIN_NAME ), emulatorUrl , MD5_CHECKSUM );
78+ new DownloadableEmulatorRunner (Arrays .asList (BIN_NAME , BIN_CMD_PORT_FLAG + port ),
79+ EMULATOR_URL , MD5_CHECKSUM );
6980 serviceHelper =
70- new LocalServiceHelper (Arrays .asList (gcloudRunner , downloadRunner ), DEFAULT_PORT );
81+ new LocalServiceHelper (Arrays .asList (gcloudRunner , downloadRunner ), port );
7182 }
7283
7384 /**
7485 * Start the local pubsub emulator through gcloud, download the zip file if user does not have
7586 * gcloud installed.
87+ *
7688 * @throws InterruptedException
7789 * @throws IOException
7890 */
7991 public void start () throws IOException , InterruptedException {
80- String blockUntilOutput = Integer .toString (DEFAULT_PORT );
92+ String blockUntilOutput = Integer .toString (port );
8193 serviceHelper .start (blockUntilOutput );
8294 }
8395
8496 /**
8597 * Reset the internal state of the emulator.
86- * @throws InterruptedException
98+ *
8799 * @throws IOException
88100 */
89- public void reset () throws IOException , InterruptedException {
101+ public void reset () throws IOException {
90102 this .serviceHelper .sendPostRequest ("/reset" );
91103 }
92104
93105 /**
94106 * Quit the local emulator and related local service.
107+ *
95108 * @throws InterruptedException
96109 * @throws IOException
97110 */
@@ -104,7 +117,7 @@ public void stop() throws IOException, InterruptedException {
104117 * Creates a channel for making requests to the in-memory service.
105118 */
106119 public ManagedChannel createChannel () {
107- return NettyChannelBuilder .forAddress (DEFAULT_HOST , DEFAULT_PORT )
120+ return NettyChannelBuilder .forAddress (DEFAULT_HOST , port )
108121 .negotiationType (NegotiationType .PLAINTEXT )
109122 .build ();
110123 }
0 commit comments