2121import java .nio .file .Files ;
2222import java .nio .file .Path ;
2323import java .nio .file .Paths ;
24- import java .util .ArrayList ;
25- import java .util .Arrays ;
26- import java .util .List ;
24+ import java .util .*;
2725import java .util .function .Supplier ;
2826import java .util .logging .Level ;
2927import java .util .logging .Logger ;
@@ -45,7 +43,7 @@ public class NatsServerRunner implements AutoCloseable {
4543
4644 private final String _executablePath ;
4745 private final Output _displayOut ;
48- private final int _port ;
46+ private final Map < String , Integer > _ports ;
4947 private final File _configFile ;
5048 private final String _cmdLine ;
5149 private Process process ;
@@ -311,7 +309,9 @@ public NatsServerRunner(NatsServerRunnerOptions natsServerRunnerOptions) throws
311309 // ----------------------------------------------------------------------------------------------------
312310 protected NatsServerRunner (Builder b ) throws IOException {
313311 _executablePath = b .executablePath == null ? getResolvedServerPath () : b .executablePath .toString ();
314- _port = b .port == null || b .port <= 0 ? nextPort () : b .port ;
312+ _ports = new HashMap <>();
313+ int constructionPort = b .port == null || b .port <= 0 ? nextPort () : b .port ;
314+ _ports .put (PORT_LINE_KEY , constructionPort );
315315
316316 if (b .output == null ) {
317317 _displayOut = DefaultOutputSupplier .get ();
@@ -336,7 +336,7 @@ protected NatsServerRunner(Builder b) throws IOException {
336336 _configFile = File .createTempFile (CONF_FILE_PREFIX , CONF_FILE_EXT );
337337 BufferedWriter writer = new BufferedWriter (new FileWriter (_configFile ));
338338 if (b .configFilePath == null || processSuppliedConfigFile (writer , b .configFilePath )) {
339- writePortLine (writer , _port );
339+ writePortLine (writer , constructionPort );
340340 }
341341
342342 if (b .configInserts != null ) {
@@ -389,7 +389,7 @@ protected NatsServerRunner(Builder b) throws IOException {
389389 }
390390 while (!process .isAlive () && --tries > 0 );
391391
392- SocketAddress addr = new InetSocketAddress ("localhost" , _port );
392+ SocketAddress addr = new InetSocketAddress ("localhost" , constructionPort );
393393 SocketChannel socketChannel = SocketChannel .open ();
394394 socketChannel .configureBlocking (true );
395395 if (connCheckTries > 0 ) {
@@ -463,24 +463,38 @@ private String getConfigSep(String configPath) {
463463 // HELPERS
464464 // ----------------------------------------------------------------------------------------------------
465465 private boolean processSuppliedConfigFile (BufferedWriter writer , Path configFilePath ) throws IOException {
466- Pattern portPattern = Pattern .compile (PORT_REGEX );
467- Matcher portMatcher = portPattern .matcher ("" );
466+ Matcher constructionPortMatcher = Pattern .compile (PORT_REGEX ). matcher ( "" );
467+ Matcher mappedPortMatcher = Pattern . compile ( PORT_MAPPED_REGEX ) .matcher ("" );
468468
469469 BufferedReader reader = new BufferedReader (new FileReader (configFilePath .toFile ()));
470470
471471 boolean needsPortLine = true ;
472472 String line = reader .readLine ();
473473 while (line != null ) {
474- portMatcher .reset (line );
475474
476475 // replacing it here allows us to not care if the port is at the top level
477476 // or for instance inside a websocket block
478- if (portMatcher .find ()) {
479- writeLine (writer , line .replace (portMatcher .group (1 ), String .valueOf (_port )));
477+ constructionPortMatcher .reset (line );
478+ if (constructionPortMatcher .find ()) {
479+ writeLine (writer , line .replace (constructionPortMatcher .group (1 ), _ports .get (PORT_LINE_KEY ).toString ()));
480480 needsPortLine = false ;
481481 }
482482 else {
483- writeLine (writer , line );
483+ mappedPortMatcher .reset (line );
484+ if (mappedPortMatcher .find ()) {
485+ int start = line .indexOf ("<" );
486+ int end = line .indexOf (">" );
487+ String key = line .substring (start + 1 , end );
488+ Integer mapped = _ports .get (key );
489+ if (mapped == null ) {
490+ mapped = nextPort ();
491+ _ports .put (key , mapped );
492+ }
493+ writeLine (writer , line .replace ("<" + key + ">" , mapped .toString ()));
494+ }
495+ else {
496+ writeLine (writer , line );
497+ }
484498 }
485499
486500 line = reader .readLine ();
@@ -523,7 +537,11 @@ public String getExecutablePath() {
523537 * @return the port number
524538 */
525539 public int getPort () {
526- return _port ;
540+ return _ports .get (PORT_LINE_KEY );
541+ }
542+
543+ public Integer getPort (String key ) {
544+ return _ports .get (key );
527545 }
528546
529547 /**
@@ -539,7 +557,7 @@ public String getConfigFile() {
539557 * @return the uri string
540558 */
541559 public String getURI () {
542- return getNatsLocalhostUri (_port );
560+ return getNatsLocalhostUri (_ports . get ( PORT_LINE_KEY ) );
543561 }
544562
545563 /**
0 commit comments