Skip to content

Commit

Permalink
Merge pull request #247 from nats-io/2.5.2
Browse files Browse the repository at this point in the history
2.5.2
  • Loading branch information
Stephen Asbury authored Jun 19, 2019
2 parents 050729b + abe763e commit 593037e
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Thumbs.db
################
*~
*.swp
.sts4-cache/*

# Gradle Files #
################
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@

# Change Log

## Version 2.5.2

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

## Version 2.5.1

* [FIXED] - #239 - cleaned up extra code after SSL connect failure
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ The java-nats client is provided in a single jar file, with a single external de

### Downloading the Jar

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).
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).

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).
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).

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).

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

```groovy
dependencies {
implementation 'io.nats:jnats:2.5.1'
implementation 'io.nats:jnats:2.5.2'
}
```

Expand All @@ -90,7 +90,7 @@ The NATS client is available on the Maven central repository, and can be importe
<dependency>
<groupId>io.nats</groupId>
<artifactId>jnats</artifactId>
<version>2.5.1</version>
<version>2.5.2</version>
</dependency>
```

Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ plugins {
// Be sure to update Nats.java with the latest version, the change log and the package-info.java
def versionMajor = 2
def versionMinor = 5
def versionPatch = 1
def versionPatch = 2
def versionModifier = ""
def jarVersion = "2.5.1"
def jarVersion = "2.5.2"
def branch = System.getenv("TRAVIS_BRANCH");

def getVersionName = { ->
Expand Down
8 changes: 5 additions & 3 deletions src/examples/java/io/nats/examples/benchmark/Benchmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public final String report() {
public final String csv() {
StringBuilder sb = new StringBuilder();
String header =
"#RunID, ClientID, MsgCount, MsgBytes, MsgsPerSec, BytesPerSec, DurationSecs";
"#RunID, ClientID, Test Msgs, MsgsPerSec, BytesPerSec, Total Msgs, Total Bytes, DurationSecs";

sb.append(String.format("%s stats: %s\n", name, this));
sb.append(header); sb.append("\n");
Expand All @@ -145,8 +145,10 @@ String csvLines(SampleGroup grp, String prefix) {
StringBuilder sb = new StringBuilder();
int j = 0;
for (Sample stat : grp.getSamples()) {
String line = String.format("%s,%s%d,%d,%d,%d,%f,%f", runId, prefix, j++, stat.msgCnt,
stat.msgBytes, stat.rate(), stat.throughput(),
String line = String.format("%s,%s%d,%d,%d,%.2f,%d,%d,%.4f", runId,
prefix, j++,
stat.getJobMsgCnt(), stat.rate(), stat.throughput(),
stat.msgCnt, stat.msgBytes,
(double) stat.duration() / 1000000000.0);
sb.append(line); sb.append("\n");
}
Expand Down
109 changes: 68 additions & 41 deletions src/examples/java/io/nats/examples/benchmark/NatsBench.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -37,10 +39,11 @@
import java.util.concurrent.atomic.AtomicLong;

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

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

private boolean secure = false;
private Benchmark bench;

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

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

public NatsBench(Properties properties) throws NoSuchAlgorithmException {
urls = properties.getProperty("bench.nats.servers", urls);
secure = Boolean.parseBoolean(
properties.getProperty("bench.nats.secure", Boolean.toString(secure)));
numMsgs = Integer.parseInt(
properties.getProperty("bench.nats.msg.count", Integer.toString(numMsgs)));
size = Integer
.parseInt(properties.getProperty("bench.nats.msg.size", Integer.toString(numSubs)));
numPubs = Integer
.parseInt(properties.getProperty("bench.nats.pubs", Integer.toString(numPubs)));
numSubs = Integer
.parseInt(properties.getProperty("bench.nats.subs", Integer.toString(numSubs)));
csv = Boolean.parseBoolean(
properties.getProperty("bench.nats.csv", Boolean.toString(csv)));
secure = Boolean.parseBoolean(properties.getProperty("bench.nats.secure", Boolean.toString(secure)));
numMsgs = Integer.parseInt(properties.getProperty("bench.nats.msg.count", Integer.toString(numMsgs)));
size = Integer.parseInt(properties.getProperty("bench.nats.msg.size", Integer.toString(numSubs)));
numPubs = Integer.parseInt(properties.getProperty("bench.nats.pubs", Integer.toString(numPubs)));
numSubs = Integer.parseInt(properties.getProperty("bench.nats.subs", Integer.toString(numSubs)));
csv = Boolean.parseBoolean(properties.getProperty("bench.nats.csv", Boolean.toString(csv)));
subject = properties.getProperty("bench.nats.subject", NUID.nextGlobal());
}

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

/**
* The conscrypt flag is provided for testing with the conscrypt jar. Using it
* through reflection is deprecated but allows the library to ship without a
* dependency. Using conscrypt should only require the jar plus the flag. For
* example, to run after building locally and using the test cert files: java
* -cp
* ./build/libs/jnats-2.5.1-SNAPSHOT-examples.jar:./build/libs/jnats-2.5.1-SNAPSHOT-fat.jar:<path
* to conscrypt.jar> \ -Djavax.net.ssl.keyStore=src/test/resources/keystore.jks
* -Djavax.net.ssl.keyStorePassword=password \
* -Djavax.net.ssl.trustStore=src/test/resources/cacerts
* -Djavax.net.ssl.trustStorePassword=password \
* io.nats.examples.autobench.NatsAutoBench tls://localhost:4443 med conscrypt
*/
if (conscrypt) {
try {
Provider provider = null;
provider = (Provider) Class.forName("org.conscrypt.OpenSSLProvider").newInstance();
Security.insertProviderAt(provider, 1);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}

if (secure) {
builder.secure();
}
Expand Down Expand Up @@ -157,9 +179,12 @@ public void run() {

class SyncSubWorker extends Worker {
final Phaser subReady;
private AtomicLong start;

SyncSubWorker(Future<Boolean> starter, Phaser subReady, Phaser finisher, int numMsgs, int size, boolean secure) {
super(starter, finisher, numMsgs, size, secure);
this.subReady = subReady;
this.start = new AtomicLong();
}

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

int receivedCount = 0;
long start = System.nanoTime();
while (receivedCount < numMsgs) {
if(sub.nextMessage(timeout) != null) {
if (receivedCount == 0) {
start.set(System.nanoTime());
}
received.incrementAndGet();
receivedCount++;
}
}
long end = System.nanoTime();

bench.addSubSample(new Sample(numMsgs, size, start, end, nc.getStatistics()));
if (start.get() > 0) {
bench.addSubSample(new Sample(numMsgs, size, start.get(), end, nc.getStatistics()));
} else {
throw new Exception("start time was never set");
}

if (stats) {
System.out.println(nc.getStatistics());
Expand Down Expand Up @@ -269,11 +300,13 @@ public void start() throws Exception {
System.out.println("Use ctrl-C to cancel.");
System.out.println();

if (this.numPubs > 0) {
if (this.numPubs > 0 && this.numSubs > 0) {
runTest("Pub Only", this.numPubs, 0);
runTest("Pub/Sub", this.numPubs, this.numSubs);
} else if (this.numPubs > 0) {
runTest("Pub Only", this.numPubs, 0);
} else {
runTest("Sub", this.numPubs, this.numSubs);
runTest("Sub Only", 0, this.numSubs);
}

System.out.println();
Expand Down Expand Up @@ -394,7 +427,6 @@ private void parseArgs(String[] args) {
String arg = it.next();
switch (arg) {
case "-s":
case "--server":
if (!it.hasNext()) {
usage();
}
Expand All @@ -403,9 +435,6 @@ private void parseArgs(String[] args) {
it.remove();
continue;
case "-tls":
if (!it.hasNext()) {
usage();
}
it.remove();
secure = true;
continue;
Expand Down Expand Up @@ -443,19 +472,17 @@ private void parseArgs(String[] args) {
it.remove();
continue;
case "-csv":
if (it.hasNext()) {
usage();
}
it.remove();
csv = true;
continue;
case "-stats":
if (it.hasNext()) {
usage();
}
it.remove();
stats = true;
continue;
case "-conscrypt":
it.remove();
conscrypt = true;
continue;
default:
System.err.printf("Unexpected token: '%s'\n", arg);
usage();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/nats/client/Nats.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public class Nats {
/**
* Current version of the library - {@value #CLIENT_VERSION}
*/
public static final String CLIENT_VERSION = "2.5.1";
public static final String CLIENT_VERSION = "2.5.2";

/**
* Current language of the library - {@value #CLIENT_LANGUAGE}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/nats/client/impl/NatsServerInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public String getRawJson() {
private static final String grabString = "\\s*\"(.+?)\"";
private static final String grabBoolean = "\\s*(true|false)";
private static final String grabNumber = "\\s*(\\d+)";
private static final String grabArray = "\\s*\\[(.+?)\\]";
private static final String grabStringArray = "\\s*\\[(\".+?\")\\]";
private static final String grabObject = "\\{(.+?)\\}";

void parseInfo(String jsonString) {
Expand All @@ -116,7 +116,7 @@ void parseInfo(String jsonString) {
Pattern portRE = Pattern.compile("\""+PORT+"\":" + grabNumber, Pattern.CASE_INSENSITIVE);
Pattern maxRE = Pattern.compile("\""+MAX_PAYLOAD+"\":" + grabNumber, Pattern.CASE_INSENSITIVE);
Pattern protoRE = Pattern.compile("\""+PROTOCOL_VERSION+"\":" + grabNumber, Pattern.CASE_INSENSITIVE);
Pattern connectRE = Pattern.compile("\""+CONNECT_URLS+"\":" + grabArray, Pattern.CASE_INSENSITIVE);
Pattern connectRE = Pattern.compile("\""+CONNECT_URLS+"\":" + grabStringArray, Pattern.CASE_INSENSITIVE);
Pattern infoObject = Pattern.compile(grabObject, Pattern.CASE_INSENSITIVE);

Matcher m = infoObject.matcher(jsonString);
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/io/nats/client/impl/NatsServerInfoTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ public void testEmptyURLParsing() {
String[] urls = {"one"};
assertTrue(Arrays.equals(info.getConnectURLs(), urls));
}

@Test
public void testIPV6InBrackets() {
String json = "{" +
"\"server_id\":\"myserver\"" + "," +
"\"connect_urls\":[\"one:4222\", \"[a:b:c]:4222\", \"[d:e:f]:4223\"]" + "," +
"\"max_payload\":100000000000" +
"}";
NatsServerInfo info = new NatsServerInfo(json);
assertEquals(info.getServerId(), "myserver");
String[] urls = {"one:4222", "[a:b:c]:4222", "[d:e:f]:4223"};
assertTrue(Arrays.equals(info.getConnectURLs(), urls));
}

@Test(expected=IllegalArgumentException.class)
public void testThrowsOnNonJson() {
Expand Down

0 comments on commit 593037e

Please sign in to comment.