@@ -307,11 +307,22 @@ public NatsServerRunner(NatsServerRunnerOptions natsServerRunnerOptions) throws
307307 // ----------------------------------------------------------------------------------------------------
308308 // ACTUAL CONSTRUCTION
309309 // ----------------------------------------------------------------------------------------------------
310+
310311 protected NatsServerRunner (Builder b ) throws IOException {
311312 _executablePath = b .executablePath == null ? getResolvedServerPath () : b .executablePath .toString ();
312- _ports = new HashMap <>();
313- int constructionPort = b .port == null || b .port <= 0 ? nextPort () : b .port ;
314- _ports .put (PORT_LINE_KEY , constructionPort );
313+ _ports = b .ports ;
314+ Integer tempPort = _ports .get (CONFIG_PORT_KEY );
315+ if (tempPort == null ) {
316+ _ports .put (CONFIG_PORT_KEY , -1 );
317+ tempPort = -1 ;
318+ }
319+ if (tempPort == -1 ) {
320+ tempPort = nextPort ();
321+ }
322+ _ports .put (USER_PORT_KEY , tempPort );
323+ int userPort = tempPort ;
324+ _ports .put (NATS_PORT_KEY , -1 );
325+ _ports .put (NON_NATS_PORT_KEY , -1 );
315326
316327 if (b .output == null ) {
317328 _displayOut = DefaultOutputSupplier .get ();
@@ -335,8 +346,12 @@ protected NatsServerRunner(Builder b) throws IOException {
335346 try {
336347 _configFile = File .createTempFile (CONF_FILE_PREFIX , CONF_FILE_EXT );
337348 BufferedWriter writer = new BufferedWriter (new FileWriter (_configFile ));
338- if (b .configFilePath == null || processSuppliedConfigFile (writer , b .configFilePath )) {
339- writePortLine (writer , constructionPort );
349+ if (b .configFilePath == null ) {
350+ _ports .put (NATS_PORT_KEY , userPort );
351+ writePortLine (writer , userPort );
352+ }
353+ else {
354+ processSuppliedConfigFile (writer , b .configFilePath );
340355 }
341356
342357 if (b .configInserts != null ) {
@@ -389,7 +404,7 @@ protected NatsServerRunner(Builder b) throws IOException {
389404 }
390405 while (!process .isAlive () && --tries > 0 );
391406
392- SocketAddress addr = new InetSocketAddress ("localhost" , constructionPort );
407+ SocketAddress addr = new InetSocketAddress ("localhost" , _ports . get ( NATS_PORT_KEY ) );
393408 SocketChannel socketChannel = SocketChannel .open ();
394409 socketChannel .configureBlocking (true );
395410 if (connCheckTries > 0 ) {
@@ -462,22 +477,40 @@ private String getConfigSep(String configPath) {
462477 // ----------------------------------------------------------------------------------------------------
463478 // HELPERS
464479 // ----------------------------------------------------------------------------------------------------
465- private boolean processSuppliedConfigFile (BufferedWriter writer , Path configFilePath ) throws IOException {
480+ private void processSuppliedConfigFile (BufferedWriter writer , Path configFilePath ) throws IOException {
466481 Matcher constructionPortMatcher = Pattern .compile (PORT_REGEX ).matcher ("" );
467482 Matcher mappedPortMatcher = Pattern .compile (PORT_MAPPED_REGEX ).matcher ("" );
468483
469484 BufferedReader reader = new BufferedReader (new FileReader (configFilePath .toFile ()));
470485
471- boolean needsPortLine = true ;
486+ boolean userTaken = false ;
487+ int userPort = _ports .get (USER_PORT_KEY ); // already ensured so it's not -1
488+ int natsPort = -1 ;
472489 String line = reader .readLine ();
490+ int level = 0 ;
473491 while (line != null ) {
474-
492+ String trim = line .trim ();
493+ if (trim .endsWith ("{" )) {
494+ level ++;
495+ }
496+ else if (trim .startsWith ("}" )) {
497+ level --;
498+ }
475499 // replacing it here allows us to not care if the port is at the top level
476500 // or for instance inside a websocket block
477501 constructionPortMatcher .reset (line );
478502 if (constructionPortMatcher .find ()) {
479- writeLine (writer , line .replace (constructionPortMatcher .group (1 ), _ports .get (PORT_LINE_KEY ).toString ()));
480- needsPortLine = false ;
503+ if (userTaken ) {
504+ throw new IOException ("Improper configuration, cannot assign port multiple times." );
505+ }
506+ userTaken = true ;
507+ if (level == 0 ) {
508+ natsPort = userPort ;
509+ }
510+ else {
511+ _ports .put (NON_NATS_PORT_KEY , userPort );
512+ }
513+ writeLine (writer , line .replace (constructionPortMatcher .group (1 ), Integer .toString (userPort )));
481514 }
482515 else {
483516 mappedPortMatcher .reset (line );
@@ -491,6 +524,12 @@ private boolean processSuppliedConfigFile(BufferedWriter writer, Path configFile
491524 _ports .put (key , mapped );
492525 }
493526 writeLine (writer , line .replace ("<" + key + ">" , mapped .toString ()));
527+ if (level == 0 ) {
528+ natsPort = mapped ;
529+ }
530+ else {
531+ _ports .put (NON_NATS_PORT_KEY , mapped );
532+ }
494533 }
495534 else {
496535 writeLine (writer , line );
@@ -502,7 +541,18 @@ private boolean processSuppliedConfigFile(BufferedWriter writer, Path configFile
502541
503542 reader .close ();
504543
505- return needsPortLine ;
544+ if (natsPort == -1 ) {
545+ if (userTaken ) {
546+ _ports .put (NATS_PORT_KEY , 4222 );
547+ }
548+ else {
549+ _ports .put (NATS_PORT_KEY , userPort );
550+ writePortLine (writer , userPort );
551+ }
552+ }
553+ else {
554+ _ports .put (NATS_PORT_KEY , natsPort );
555+ }
506556 }
507557
508558 private void writePortLine (BufferedWriter writer , int port ) throws IOException {
@@ -537,7 +587,23 @@ public String getExecutablePath() {
537587 * @return the port number
538588 */
539589 public int getPort () {
540- return _ports .get (PORT_LINE_KEY );
590+ return getUserPort ();
591+ }
592+
593+ public int getUserPort () {
594+ return _ports .get (USER_PORT_KEY );
595+ }
596+
597+ public int getNatsPort () {
598+ return _ports .get (NATS_PORT_KEY );
599+ }
600+
601+ public int getConfigPort () {
602+ return _ports .get (CONFIG_PORT_KEY );
603+ }
604+
605+ public int getNonNatsPort () {
606+ return _ports .get (NON_NATS_PORT_KEY );
541607 }
542608
543609 public Integer getPort (String key ) {
@@ -557,7 +623,7 @@ public String getConfigFile() {
557623 * @return the uri string
558624 */
559625 public String getURI () {
560- return getNatsLocalhostUri (_ports . get ( PORT_LINE_KEY ));
626+ return getNatsLocalhostUri (getNatsPort ( ));
561627 }
562628
563629 /**
@@ -604,7 +670,7 @@ public void close() throws Exception {
604670 // Builder
605671 // ====================================================================================================
606672 public static class Builder {
607- Integer port ;
673+ Map < String , Integer > ports = new HashMap <>() ;
608674 DebugLevel debugLevel ;
609675 boolean jetstream ;
610676 Path configFilePath ;
@@ -620,7 +686,24 @@ public static class Builder {
620686 boolean fullErrorReportOnStartup = true ;
621687
622688 public Builder port (Integer port ) {
623- this .port = port ;
689+ return port (CONFIG_PORT_KEY , port );
690+ }
691+
692+ public Builder port (String key , Integer port ) {
693+ if (port == null ) {
694+ ports .remove (key );
695+ }
696+ else {
697+ ports .put (key , port );
698+ }
699+ return this ;
700+ }
701+
702+ public Builder ports (Map <String , Integer > ports ) {
703+ this .ports .clear ();
704+ if (ports != null ) {
705+ this .ports .putAll (ports );
706+ }
624707 return this ;
625708 }
626709
@@ -719,8 +802,8 @@ public Builder connectCheckTries(Integer connectCheckTries) {
719802 return this ;
720803 }
721804
722- public Builder fullErrorReportOnStartup (boolean expandedError ) {
723- this .fullErrorReportOnStartup = expandedError ;
805+ public Builder fullErrorReportOnStartup (boolean fullErrorReportOnStartup ) {
806+ this .fullErrorReportOnStartup = fullErrorReportOnStartup ;
724807 return this ;
725808 }
726809
0 commit comments