Skip to content

Commit 593037e

Browse files
author
Stephen Asbury
authored
Merge pull request #247 from nats-io/2.5.2
2.5.2
2 parents 050729b + abe763e commit 593037e

File tree

9 files changed

+104
-53
lines changed

9 files changed

+104
-53
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Thumbs.db
3939
################
4040
*~
4141
*.swp
42+
.sts4-cache/*
4243

4344
# Gradle Files #
4445
################

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11

22
# Change Log
33

4+
## Version 2.5.2
5+
6+
* [FIXED] - #244 - fixed an issue with parsing ipv6 addresses in the info JSON, added unit test for parser
7+
* [FIXED] - #245 - fixed a timing bug in nats bench, now subscribers start timing at the first receive
8+
* [FIXED/CHANGED] - #246 - fixed a confusing output from nats bench in CSV mode, now the test count and the total count are printed
9+
* [ADDED] - spring cache to git ignore file
10+
* [ADDED] - support for running nats bench with conscrypt
11+
412
## Version 2.5.1
513

614
* [FIXED] - #239 - cleaned up extra code after SSL connect failure

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ The java-nats client is provided in a single jar file, with a single external de
5252

5353
### Downloading the Jar
5454

55-
You can download the latest jar at [https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.1/jnats-2.5.1.jar](https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.1/jnats-2.5.1.jar).
55+
You can download the latest jar at [https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.2/jnats-2.5.2.jar](https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.2/jnats-2.5.2.jar).
5656

57-
The examples are available at [https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.1/jnats-2.5.1-examples.jar](https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.1/jnats-2.5.1-examples.jar).
57+
The examples are available at [https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.2/jnats-2.5.2-examples.jar](https://search.maven.org/remotecontent?filepath=io/nats/jnats/2.5.2/jnats-2.5.2-examples.jar).
5858

5959
To use NKeys, you will need the ed25519 library, which can be downloaded at [https://repo1.maven.org/maven2/net/i2p/crypto/eddsa/0.3.0/eddsa-0.3.0.jar](https://repo1.maven.org/maven2/net/i2p/crypto/eddsa/0.3.0/eddsa-0.3.0.jar).
6060

@@ -64,7 +64,7 @@ The NATS client is available in the Maven central repository, and can be importe
6464

6565
```groovy
6666
dependencies {
67-
implementation 'io.nats:jnats:2.5.1'
67+
implementation 'io.nats:jnats:2.5.2'
6868
}
6969
```
7070

@@ -90,7 +90,7 @@ The NATS client is available on the Maven central repository, and can be importe
9090
<dependency>
9191
<groupId>io.nats</groupId>
9292
<artifactId>jnats</artifactId>
93-
<version>2.5.1</version>
93+
<version>2.5.2</version>
9494
</dependency>
9595
```
9696

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ plugins {
1414
// Be sure to update Nats.java with the latest version, the change log and the package-info.java
1515
def versionMajor = 2
1616
def versionMinor = 5
17-
def versionPatch = 1
17+
def versionPatch = 2
1818
def versionModifier = ""
19-
def jarVersion = "2.5.1"
19+
def jarVersion = "2.5.2"
2020
def branch = System.getenv("TRAVIS_BRANCH");
2121

2222
def getVersionName = { ->

src/examples/java/io/nats/examples/benchmark/Benchmark.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public final String report() {
132132
public final String csv() {
133133
StringBuilder sb = new StringBuilder();
134134
String header =
135-
"#RunID, ClientID, MsgCount, MsgBytes, MsgsPerSec, BytesPerSec, DurationSecs";
135+
"#RunID, ClientID, Test Msgs, MsgsPerSec, BytesPerSec, Total Msgs, Total Bytes, DurationSecs";
136136

137137
sb.append(String.format("%s stats: %s\n", name, this));
138138
sb.append(header); sb.append("\n");
@@ -145,8 +145,10 @@ String csvLines(SampleGroup grp, String prefix) {
145145
StringBuilder sb = new StringBuilder();
146146
int j = 0;
147147
for (Sample stat : grp.getSamples()) {
148-
String line = String.format("%s,%s%d,%d,%d,%d,%f,%f", runId, prefix, j++, stat.msgCnt,
149-
stat.msgBytes, stat.rate(), stat.throughput(),
148+
String line = String.format("%s,%s%d,%d,%d,%.2f,%d,%d,%.4f", runId,
149+
prefix, j++,
150+
stat.getJobMsgCnt(), stat.rate(), stat.throughput(),
151+
stat.msgCnt, stat.msgBytes,
150152
(double) stat.duration() / 1000000000.0);
151153
sb.append(line); sb.append("\n");
152154
}

src/examples/java/io/nats/examples/benchmark/NatsBench.java

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.io.IOException;
2222
import java.io.InputStream;
2323
import java.security.NoSuchAlgorithmException;
24+
import java.security.Provider;
25+
import java.security.Security;
2426
import java.time.Duration;
2527
import java.util.ArrayList;
2628
import java.util.Arrays;
@@ -37,10 +39,11 @@
3739
import java.util.concurrent.atomic.AtomicLong;
3840

3941
/**
40-
* A utility class for measuring NATS performance, similar to the version in go and node.
41-
* The various tradeoffs to make this code act/work like the other versions, including the
42-
* previous java version, make it a bit &quot;crufty&quot; for an example. See autobench for
43-
* an example with minimal boilerplate.
42+
* A utility class for measuring NATS performance, similar to the version in go
43+
* and node. The various tradeoffs to make this code act/work like the other
44+
* versions, including the previous java version, make it a bit
45+
* &quot;crufty&quot; for an example. See autobench for an example with minimal
46+
* boilerplate.
4447
*/
4548
public class NatsBench {
4649
final BlockingQueue<Throwable> errorQueue = new LinkedBlockingQueue<Throwable>();
@@ -57,23 +60,24 @@ public class NatsBench {
5760
private final AtomicLong received = new AtomicLong();
5861
private boolean csv = false;
5962
private boolean stats = false;
63+
private boolean conscrypt = false;
6064

6165
private Thread shutdownHook;
6266
private final AtomicBoolean shutdown = new AtomicBoolean(false);
6367

6468
private boolean secure = false;
6569
private Benchmark bench;
6670

67-
static final String usageString =
68-
"\nUsage: java NatsBench [-s server] [-tls] [-np num] [-ns num] [-n num] [-ms size] "
69-
+ "[-csv file] <subject>\n\nOptions:\n"
70-
+ " -s <urls> The nats server URLs (comma-separated), use tls:// or opentls:// to require tls\n"
71-
+ " -np Number of concurrent publishers (1)\n"
72-
+ " -ns Number of concurrent subscribers (0)\n"
73-
+ " -n Number of messages to publish (100,000)\n"
74-
+ " -ms Size of the message (128)\n"
75-
+ " -csv Print results to stdout as csv (false)\n"
76-
+ " -stats Track and print out internal statistics (false)\n";
71+
static final String usageString = "\nUsage: java NatsBench [-s server] [-tls] [-np num] [-ns num] [-n num] [-ms size] "
72+
+ "[-csv file] <subject>\n\nOptions:\n"
73+
+ " -s <urls> The nats server URLs (comma-separated), use tls:// or opentls:// to require tls\n"
74+
+ " -np <int> Number of concurrent publishers (1)\n"
75+
+ " -ns <int> Number of concurrent subscribers (0)\n"
76+
+ " -n <int> Number of messages to publish (100,000)\n"
77+
+ " -ms <int> Size of the message (128)\n"
78+
+ " -csv Print results to stdout as csv (false)\n"
79+
+ " -tls Set the secure flag on the SSL context to true (false)\n"
80+
+ " -stats Track and print out internal statistics (false)\n";
7781

7882
public NatsBench(String[] args) throws Exception {
7983
if (args == null || args.length < 1) {
@@ -85,18 +89,12 @@ public NatsBench(String[] args) throws Exception {
8589

8690
public NatsBench(Properties properties) throws NoSuchAlgorithmException {
8791
urls = properties.getProperty("bench.nats.servers", urls);
88-
secure = Boolean.parseBoolean(
89-
properties.getProperty("bench.nats.secure", Boolean.toString(secure)));
90-
numMsgs = Integer.parseInt(
91-
properties.getProperty("bench.nats.msg.count", Integer.toString(numMsgs)));
92-
size = Integer
93-
.parseInt(properties.getProperty("bench.nats.msg.size", Integer.toString(numSubs)));
94-
numPubs = Integer
95-
.parseInt(properties.getProperty("bench.nats.pubs", Integer.toString(numPubs)));
96-
numSubs = Integer
97-
.parseInt(properties.getProperty("bench.nats.subs", Integer.toString(numSubs)));
98-
csv = Boolean.parseBoolean(
99-
properties.getProperty("bench.nats.csv", Boolean.toString(csv)));
92+
secure = Boolean.parseBoolean(properties.getProperty("bench.nats.secure", Boolean.toString(secure)));
93+
numMsgs = Integer.parseInt(properties.getProperty("bench.nats.msg.count", Integer.toString(numMsgs)));
94+
size = Integer.parseInt(properties.getProperty("bench.nats.msg.size", Integer.toString(numSubs)));
95+
numPubs = Integer.parseInt(properties.getProperty("bench.nats.pubs", Integer.toString(numPubs)));
96+
numSubs = Integer.parseInt(properties.getProperty("bench.nats.subs", Integer.toString(numSubs)));
97+
csv = Boolean.parseBoolean(properties.getProperty("bench.nats.csv", Boolean.toString(csv)));
10098
subject = properties.getProperty("bench.nats.subject", NUID.nextGlobal());
10199
}
102100

@@ -106,7 +104,7 @@ Options prepareOptions(boolean secure) throws NoSuchAlgorithmException {
106104
builder.noReconnect();
107105
builder.connectionName("NatsBench");
108106
builder.servers(servers);
109-
builder.errorListener(new ErrorListener(){
107+
builder.errorListener(new ErrorListener() {
110108
@Override
111109
public void errorOccurred(Connection conn, String error) {
112110
System.out.printf("An error occurred %s\n", error);
@@ -128,6 +126,30 @@ public void slowConsumerDetected(Connection conn, Consumer consumer) {
128126
builder.turnOnAdvancedStats();
129127
}
130128

129+
/**
130+
* The conscrypt flag is provided for testing with the conscrypt jar. Using it
131+
* through reflection is deprecated but allows the library to ship without a
132+
* dependency. Using conscrypt should only require the jar plus the flag. For
133+
* example, to run after building locally and using the test cert files: java
134+
* -cp
135+
* ./build/libs/jnats-2.5.1-SNAPSHOT-examples.jar:./build/libs/jnats-2.5.1-SNAPSHOT-fat.jar:<path
136+
* to conscrypt.jar> \ -Djavax.net.ssl.keyStore=src/test/resources/keystore.jks
137+
* -Djavax.net.ssl.keyStorePassword=password \
138+
* -Djavax.net.ssl.trustStore=src/test/resources/cacerts
139+
* -Djavax.net.ssl.trustStorePassword=password \
140+
* io.nats.examples.autobench.NatsAutoBench tls://localhost:4443 med conscrypt
141+
*/
142+
if (conscrypt) {
143+
try {
144+
Provider provider = null;
145+
provider = (Provider) Class.forName("org.conscrypt.OpenSSLProvider").newInstance();
146+
Security.insertProviderAt(provider, 1);
147+
} catch (Exception e) {
148+
e.printStackTrace();
149+
System.exit(-1);
150+
}
151+
}
152+
131153
if (secure) {
132154
builder.secure();
133155
}
@@ -157,9 +179,12 @@ public void run() {
157179

158180
class SyncSubWorker extends Worker {
159181
final Phaser subReady;
182+
private AtomicLong start;
183+
160184
SyncSubWorker(Future<Boolean> starter, Phaser subReady, Phaser finisher, int numMsgs, int size, boolean secure) {
161185
super(starter, finisher, numMsgs, size, secure);
162186
this.subReady = subReady;
187+
this.start = new AtomicLong();
163188
}
164189

165190
@Override
@@ -180,16 +205,22 @@ public void run() {
180205
Duration timeout = Duration.ofMillis(1000);
181206

182207
int receivedCount = 0;
183-
long start = System.nanoTime();
184208
while (receivedCount < numMsgs) {
185209
if(sub.nextMessage(timeout) != null) {
210+
if (receivedCount == 0) {
211+
start.set(System.nanoTime());
212+
}
186213
received.incrementAndGet();
187214
receivedCount++;
188215
}
189216
}
190217
long end = System.nanoTime();
191218

192-
bench.addSubSample(new Sample(numMsgs, size, start, end, nc.getStatistics()));
219+
if (start.get() > 0) {
220+
bench.addSubSample(new Sample(numMsgs, size, start.get(), end, nc.getStatistics()));
221+
} else {
222+
throw new Exception("start time was never set");
223+
}
193224

194225
if (stats) {
195226
System.out.println(nc.getStatistics());
@@ -269,11 +300,13 @@ public void start() throws Exception {
269300
System.out.println("Use ctrl-C to cancel.");
270301
System.out.println();
271302

272-
if (this.numPubs > 0) {
303+
if (this.numPubs > 0 && this.numSubs > 0) {
273304
runTest("Pub Only", this.numPubs, 0);
274305
runTest("Pub/Sub", this.numPubs, this.numSubs);
306+
} else if (this.numPubs > 0) {
307+
runTest("Pub Only", this.numPubs, 0);
275308
} else {
276-
runTest("Sub", this.numPubs, this.numSubs);
309+
runTest("Sub Only", 0, this.numSubs);
277310
}
278311

279312
System.out.println();
@@ -394,7 +427,6 @@ private void parseArgs(String[] args) {
394427
String arg = it.next();
395428
switch (arg) {
396429
case "-s":
397-
case "--server":
398430
if (!it.hasNext()) {
399431
usage();
400432
}
@@ -403,9 +435,6 @@ private void parseArgs(String[] args) {
403435
it.remove();
404436
continue;
405437
case "-tls":
406-
if (!it.hasNext()) {
407-
usage();
408-
}
409438
it.remove();
410439
secure = true;
411440
continue;
@@ -443,19 +472,17 @@ private void parseArgs(String[] args) {
443472
it.remove();
444473
continue;
445474
case "-csv":
446-
if (it.hasNext()) {
447-
usage();
448-
}
449475
it.remove();
450476
csv = true;
451477
continue;
452478
case "-stats":
453-
if (it.hasNext()) {
454-
usage();
455-
}
456479
it.remove();
457480
stats = true;
458481
continue;
482+
case "-conscrypt":
483+
it.remove();
484+
conscrypt = true;
485+
continue;
459486
default:
460487
System.err.printf("Unexpected token: '%s'\n", arg);
461488
usage();

src/main/java/io/nats/client/Nats.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public class Nats {
7272
/**
7373
* Current version of the library - {@value #CLIENT_VERSION}
7474
*/
75-
public static final String CLIENT_VERSION = "2.5.1";
75+
public static final String CLIENT_VERSION = "2.5.2";
7676

7777
/**
7878
* Current language of the library - {@value #CLIENT_LANGUAGE}

src/main/java/io/nats/client/impl/NatsServerInfo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public String getRawJson() {
102102
private static final String grabString = "\\s*\"(.+?)\"";
103103
private static final String grabBoolean = "\\s*(true|false)";
104104
private static final String grabNumber = "\\s*(\\d+)";
105-
private static final String grabArray = "\\s*\\[(.+?)\\]";
105+
private static final String grabStringArray = "\\s*\\[(\".+?\")\\]";
106106
private static final String grabObject = "\\{(.+?)\\}";
107107

108108
void parseInfo(String jsonString) {
@@ -116,7 +116,7 @@ void parseInfo(String jsonString) {
116116
Pattern portRE = Pattern.compile("\""+PORT+"\":" + grabNumber, Pattern.CASE_INSENSITIVE);
117117
Pattern maxRE = Pattern.compile("\""+MAX_PAYLOAD+"\":" + grabNumber, Pattern.CASE_INSENSITIVE);
118118
Pattern protoRE = Pattern.compile("\""+PROTOCOL_VERSION+"\":" + grabNumber, Pattern.CASE_INSENSITIVE);
119-
Pattern connectRE = Pattern.compile("\""+CONNECT_URLS+"\":" + grabArray, Pattern.CASE_INSENSITIVE);
119+
Pattern connectRE = Pattern.compile("\""+CONNECT_URLS+"\":" + grabStringArray, Pattern.CASE_INSENSITIVE);
120120
Pattern infoObject = Pattern.compile(grabObject, Pattern.CASE_INSENSITIVE);
121121

122122
Matcher m = infoObject.matcher(jsonString);

src/test/java/io/nats/client/impl/NatsServerInfoTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ public void testEmptyURLParsing() {
6868
String[] urls = {"one"};
6969
assertTrue(Arrays.equals(info.getConnectURLs(), urls));
7070
}
71+
72+
@Test
73+
public void testIPV6InBrackets() {
74+
String json = "{" +
75+
"\"server_id\":\"myserver\"" + "," +
76+
"\"connect_urls\":[\"one:4222\", \"[a:b:c]:4222\", \"[d:e:f]:4223\"]" + "," +
77+
"\"max_payload\":100000000000" +
78+
"}";
79+
NatsServerInfo info = new NatsServerInfo(json);
80+
assertEquals(info.getServerId(), "myserver");
81+
String[] urls = {"one:4222", "[a:b:c]:4222", "[d:e:f]:4223"};
82+
assertTrue(Arrays.equals(info.getConnectURLs(), urls));
83+
}
7184

7285
@Test(expected=IllegalArgumentException.class)
7386
public void testThrowsOnNonJson() {

0 commit comments

Comments
 (0)