Skip to content

Commit 6791a6f

Browse files
authored
Allow for multiple generated ports by allowing to map additional ones with a name (#28)
1 parent 3d66be2 commit 6791a6f

File tree

7 files changed

+114
-32
lines changed

7 files changed

+114
-32
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
id 'signing'
1212
}
1313

14-
def jarVersion = "1.2.6"
14+
def jarVersion = "1.2.7"
1515
group = 'io.nats'
1616

1717
def isMerge = System.getenv("BUILD_EVENT") == "push"

src/main/java/nats/io/NatsRunnerUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ public abstract class NatsRunnerUtils {
3434
public static final String CONF_FILE_PREFIX = "nats_java_test";
3535
public static final String CONF_FILE_EXT = ".conf";
3636
public static final String PORT_REGEX = "port: (\\d+)";
37+
public static final String PORT_MAPPED_REGEX = "port: <(\\w+)>";
3738
public static final String PORT_PROPERTY = "port: ";
39+
public static final String PORT_LINE_KEY = "port_line_key";
3840
public static final int DEFAULT_CLUSTER_COUNT = 3;
3941
public static final String DEFAULT_CLUSTER_NAME = "cluster";
4042
public static final String DEFAULT_SERVER_NAME_PREFIX = "server";

src/main/java/nats/io/NatsServerRunner.java

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@
2121
import java.nio.file.Files;
2222
import java.nio.file.Path;
2323
import java.nio.file.Paths;
24-
import java.util.ArrayList;
25-
import java.util.Arrays;
26-
import java.util.List;
24+
import java.util.*;
2725
import java.util.function.Supplier;
2826
import java.util.logging.Level;
2927
import 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
/**

src/test/java/nats/io/NatsServerRunnerTest.java

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.logging.Logger;
3030
import java.util.stream.Stream;
3131

32+
import static nats.io.NatsRunnerUtils.PORT_LINE_KEY;
3233
import static nats.io.NatsServerRunner.DefaultLoggingSupplier;
3334
import static nats.io.NatsServerRunner.getDefaultOutputSupplier;
3435
import static org.junit.jupiter.api.Assertions.*;
@@ -37,10 +38,10 @@ public class NatsServerRunnerTest extends TestBase {
3738

3839
private static Stream<Arguments> debugAndJetStreamArgs() {
3940
return Stream.of(
40-
Arguments.of(false, false),
41-
Arguments.of(true, false),
42-
Arguments.of(false, true),
43-
Arguments.of(true, true)
41+
Arguments.of(false, false),
42+
Arguments.of(true, false),
43+
Arguments.of(false, true),
44+
Arguments.of(true, true)
4445
);
4546
}
4647

@@ -131,10 +132,10 @@ public void testCustomsBuilder() throws Exception {
131132

132133
private static Stream<Arguments> withConfigArgs() {
133134
return Stream.of(
134-
Arguments.of("port_not_specified.conf", true),
135-
Arguments.of("port_specified.conf", true),
136-
Arguments.of("websocket.conf", false),
137-
Arguments.of("ws.conf", false)
135+
Arguments.of("port_not_specified.conf", true),
136+
Arguments.of("port_specified.conf", true),
137+
Arguments.of("websocket.conf", false),
138+
Arguments.of("ws.conf", false)
138139
);
139140
}
140141

@@ -169,6 +170,48 @@ public void testWithConfigBuilder(String configFile, boolean checkConnect) throw
169170
}
170171
}
171172

173+
private static Stream<Arguments> mappedPortsArgs() {
174+
return Stream.of(
175+
Arguments.of("port_mapped_needs_port_line_yes.conf", false),
176+
Arguments.of("port_mapped_needs_port_line_no.conf", true)
177+
);
178+
}
179+
180+
@ParameterizedTest
181+
@MethodSource("mappedPortsArgs")
182+
public void testMappedPorts(String configFile, boolean mainFirst) throws Exception {
183+
try (NatsServerRunner runner = new NatsServerRunner(SOURCE_CONFIG_FILE_PATH + configFile, null, -1, false)) {
184+
Integer mainPort = runner.getPort(PORT_LINE_KEY);
185+
Integer wsPort = runner.getPort("ws");
186+
assertNotNull(mainPort);
187+
assertNotNull(wsPort);
188+
189+
String mainString = "port: " + mainPort;
190+
String wsString = "port: " + wsPort;
191+
192+
int mainLine = -1;
193+
int wsLine = -1;
194+
195+
List<String> lines = getConfigLinesRemoveEmpty(runner);
196+
for (int i = 0; i < lines.size(); i++) {
197+
String line = lines.get(i);
198+
if (line.contains(mainString)) {
199+
mainLine = i;
200+
}
201+
else if (line.contains(wsString)) {
202+
wsLine = i;
203+
}
204+
}
205+
if (mainFirst) {
206+
assertTrue(mainLine < wsLine);
207+
}
208+
else {
209+
assertFalse(mainLine < wsLine);
210+
}
211+
connect(runner);
212+
}
213+
}
214+
172215
@Test
173216
public void testBuilder() {
174217
Path p = Paths.get(".");
@@ -274,7 +317,6 @@ public void testBadConfig() throws Exception {
274317
}
275318
catch (Exception e) {
276319
assertTrue(e.getMessage().contains("nats-server: Parse error on line 2"));
277-
System.out.println(e);
278320
}
279321
}
280322
}

src/test/java/nats/io/TestBase.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
public class TestBase {
3333

3434
protected static final String SOURCE_CONFIG_FILE_PATH = "src/test/resources/";
35-
35+
3636
protected static final byte[] CONNECT_BYTES = "CONNECT {\"lang\":\"java\",\"version\":\"9.99.9\",\"protocol\":1,\"verbose\":false,\"pedantic\":false,\"tls_required\":false,\"echo\":true,\"headers\":true,\"no_responders\":true}\r\n".getBytes();
3737

3838
static {
@@ -65,21 +65,18 @@ protected void validateConfigLines(NatsServerRunner runner) throws IOException {
6565
}
6666

6767
protected void validateConfigLines(NatsServerRunner runner, String configFile, String[] configInserts) throws IOException {
68+
//noinspection resource
6869
List<String> expected = Files.lines(new File(SOURCE_CONFIG_FILE_PATH + configFile).toPath())
6970
.map(String::trim)
70-
.filter(s -> s.length() > 0)
71+
.filter(s -> !s.isEmpty())
7172
.filter(s -> !s.contains("port"))
7273
.collect(toList());
7374
Collections.addAll(expected, configInserts);
7475
validateConfigLines(runner, expected);
7576
}
7677

7778
protected void validateConfigLines(NatsServerRunner runner, List<String> expected) throws IOException {
78-
List<String> lines = Files.lines(new File(runner.getConfigFile()).toPath())
79-
.map(String::trim)
80-
.filter(s -> s.length() > 0)
81-
.collect(toUnmodifiableList());
82-
79+
List<String> lines = getConfigLinesRemoveEmpty(runner);
8380
assertTrue(lines.contains("port: " + runner.getPort()));
8481
if (expected != null) {
8582
for (String ex : expected) {
@@ -88,6 +85,15 @@ protected void validateConfigLines(NatsServerRunner runner, List<String> expecte
8885
}
8986
}
9087

88+
protected static List<String> getConfigLinesRemoveEmpty(NatsServerRunner runner) throws IOException {
89+
//noinspection resource
90+
List<String> lines = Files.lines(new File(runner.getConfigFile()).toPath())
91+
.map(String::trim)
92+
.filter(s -> !s.isEmpty())
93+
.collect(toUnmodifiableList());
94+
return lines;
95+
}
96+
9197
protected void connect(NatsServerRunner runner) throws IOException {
9298
Socket socket = new Socket();
9399
SocketAddress socketAddress = new InetSocketAddress("127.0.0.1", runner.getPort());
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# This file has port specified to map/overwrite
2+
3+
port: 0
4+
5+
ws {
6+
port: <ws>
7+
no_tls: true
8+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This file has port specified to map/overwrite
2+
3+
ws {
4+
port: <ws>
5+
no_tls: true
6+
}

0 commit comments

Comments
 (0)