Examples can now be run at command line by Gradle

* Update README to reflect use of Gradle for build.
* Add gradle tasks to run the NIO and Netty examples.
* Ensure both examples exit quickly.
This commit is contained in:
Stuart Stock
2018-01-27 21:20:49 -06:00
parent 7a15d0143a
commit 580dd62153
4 changed files with 67 additions and 20 deletions

View File

@ -21,8 +21,17 @@ created by Adam Langley and Robert Obryk.
exploring the [Nearenough API and details of Roughtime messages](https://int08h.com/post/roughtime-message-anatomy/). exploring the [Nearenough API and details of Roughtime messages](https://int08h.com/post/roughtime-message-anatomy/).
## Building ## Building
Nearenough bundles all required dependencies in the `lib` directory. Add those `.jar` files to Gradle is used to build Nearenough.
your IDE's project classpath. Building is IDE-only for the moment.
```bash
$ ./gradlew nioExample
```
and
```bash
$ ./gradlew nettyExample
```
## Quickstart ## Quickstart
@ -75,7 +84,7 @@ If you would like to contribute to Nearenough, please see the guidelines in
[CONTRIBUTING.md](../master/CONTRIBUTING.md). [CONTRIBUTING.md](../master/CONTRIBUTING.md).
## Copyright and License ## Copyright and License
Nearenough is Copyright (c) 2017 int08h LLC. All rights reserved. Nearenough is Copyright (c) 2017-2018 int08h LLC. All rights reserved.
int08h LLC licenses Nearenough (the "Software") to you under the Apache License, version 2.0 int08h LLC licenses Nearenough (the "Software") to you under the Apache License, version 2.0
(the "License"); you may not use this Software except in compliance with the License. You may obtain (the "License"); you may not use this Software except in compliance with the License. You may obtain

View File

@ -1,16 +1,49 @@
//
// Gradle build for Nearenough
//
// Copyright (c) 2017-2018 int08h LLC. All rights reserved.
//
repositories { repositories {
jcenter() jcenter()
} }
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
dependencies { dependencies {
// local snapshot of Ed25519 // local snapshot of Ed25519
compile files('lib/eddsa-0.1.0.jar') compile files('lib/eddsa-0.1.0.jar')
compile 'io.netty:netty-all:4.1.16.Final' compile 'io.netty:netty-all:4.1.20.Final'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
} }
// Suppress "Illegal reflective access" warnings on Java 9
def shouldAddOpens = JavaVersion.current().java9Compatible
// Runs the NIO example
task nioExample(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'nearenough.examples.NioClient'
if (shouldAddOpens) {
jvmArgs = ['--add-opens', 'java.base/java.nio=ALL-UNNAMED']
}
}
// Runs the NIO example
task nettyExample(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'nearenough.examples.NettyClient'
if (shouldAddOpens) {
jvmArgs = [
'--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED',
'--add-opens', 'java.base/java.nio=ALL-UNNAMED'
]
}
}

View File

@ -13,6 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
package nearenough.examples;
import static nearenough.util.BytesUtil.hexToBytes; import static nearenough.util.BytesUtil.hexToBytes;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
@ -26,8 +28,8 @@ import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.timeout.ReadTimeoutException; import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.ReadTimeoutHandler;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException;
import java.time.Instant; import java.time.Instant;
import nearenough.client.RoughtimeClient; import nearenough.client.RoughtimeClient;
import nearenough.protocol.RtMessage; import nearenough.protocol.RtMessage;
@ -70,9 +72,9 @@ public final class NettyClient {
// Sends the request to the Roughtime server // Sends the request to the Roughtime server
ctx.writeAndFlush(new DatagramPacket(encodedMsg, addr)) ctx.writeAndFlush(new DatagramPacket(encodedMsg, addr))
.addListener(fut -> { .addListener(future -> {
if (!fut.isSuccess()) { if (!future.isSuccess()) {
System.out.println("Send failed " + fut.cause().getMessage()); System.out.println("Send failed " + future.cause().getMessage());
} }
}); });
} }
@ -114,7 +116,7 @@ public final class NettyClient {
System.out.println("Response INVALID: " + client.invalidResponseCause().getMessage()); System.out.println("Response INVALID: " + client.invalidResponseCause().getMessage());
} }
ctx.close(); ctx.close().addListener(unused -> System.exit(0));
} }
@Override @Override
@ -130,16 +132,15 @@ public final class NettyClient {
} }
} }
public static void main(String[] args) throws InterruptedException, NoSuchAlgorithmException { public static void main(String[] args) throws InterruptedException {
InetSocketAddress addr = new InetSocketAddress(GOOGLE_SERVER_HOST, GOOGLE_SERVER_PORT); InetSocketAddress addr = new InetSocketAddress(GOOGLE_SERVER_HOST, GOOGLE_SERVER_PORT);
System.out.printf("Sending request to %s\n", addr); System.out.printf("Sending request to %s\n", addr);
// Below is Netty boilerplate for setting-up an event loop and registering a handler // Below is Netty boilerplate for setting-up an event loop and registering a handler
NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
NioEventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap() Bootstrap bootstrap = new Bootstrap()
.group(group) .group(nioEventLoopGroup)
.remoteAddress(addr) .remoteAddress(addr)
.channel(NioDatagramChannel.class) .channel(NioDatagramChannel.class)
.handler(new ChannelInitializer<NioDatagramChannel>() { .handler(new ChannelInitializer<NioDatagramChannel>() {
@ -152,14 +153,14 @@ public final class NettyClient {
}); });
ChannelFuture connectFuture = bootstrap.connect(); ChannelFuture connectFuture = bootstrap.connect();
connectFuture.addListener(fut -> { connectFuture.addListener(future -> {
if (!fut.isSuccess()) { if (!future.isSuccess()) {
System.out.println("Connect fail:"); System.out.println("Connect fail:");
System.out.println(fut.cause().getMessage()); System.out.println(future.cause().getMessage());
} }
}); });
connectFuture.channel().closeFuture().sync(); connectFuture.channel().closeFuture().sync();
group.shutdownGracefully(); nioEventLoopGroup.shutdownGracefully();
} }
} }

View File

@ -12,10 +12,12 @@
* either express or implied. See the License for the specific language governing permissions and * either express or implied. See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package nearenough.examples;
import static nearenough.util.BytesUtil.hexToBytes; import static nearenough.util.BytesUtil.hexToBytes;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.StandardProtocolFamily; import java.net.StandardProtocolFamily;
@ -48,7 +50,6 @@ public final class NioClient {
// Nonblocking NIO UDP channel for the remote Roughtime server // Nonblocking NIO UDP channel for the remote Roughtime server
DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET); DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET);
channel.configureBlocking(false); channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(GOOGLE_SERVER_PORT));
// Create a new RoughtimeClient instance // Create a new RoughtimeClient instance
RoughtimeClient client = new RoughtimeClient(GOOGLE_SERVER_PUBKEY); RoughtimeClient client = new RoughtimeClient(GOOGLE_SERVER_PUBKEY);
@ -59,7 +60,8 @@ public final class NioClient {
// Encode for transmission // Encode for transmission
ByteBuf encodedRequest = RtWire.toWire(request); ByteBuf encodedRequest = RtWire.toWire(request);
// Send the encoded request, converting the Netty ByteBuf to a Java ByteBuffer for NIO use. // Send the message
channel.send(encodedRequest.nioBuffer(), addr);
int bytesWritten = channel.send(encodedRequest.nioBuffer(), addr); int bytesWritten = channel.send(encodedRequest.nioBuffer(), addr);
// Ensure the message was sent // Ensure the message was sent
@ -118,5 +120,7 @@ public final class NioClient {
// No reply within five seconds // No reply within five seconds
System.out.println("No response from " + addr); System.out.println("No response from " + addr);
} }
System.exit(0);
} }
} }