diff --git a/SUMMARY.md b/SUMMARY.md index 5590927..08725c7 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -54,11 +54,15 @@ ## Developing With NATS +* [Intro](developer/README.md) + * [Concepts](developer/concepts/intro.md) + * [Subject-Based Messaging](developer/concepts/subjects.md) * [Publish-Subscribe](developer/concepts/pubsub.md) * [Request-Reply](developer/concepts/reqreply.md) - * [Using Queues to Share Work](developer/concepts/queue.md) - * [Subject-Based Messaging](developer/concepts/subjects.md) + * [Queue Groups](developer/concepts/queue.md) + * [Acknowledgements](developer/concepts/acks.md) + * [Sequence Numbers](developer/concepts/seq_num.md) * [Connecting](developer/connecting/intro.md) * [Connecting to the Default Server](developer/connecting/default_server.md) @@ -80,6 +84,8 @@ * [Securing Connections](developer/security/intro.md) * [Authenticating with a User and Password](developer/security/userpass.md) * [Authenticating with a Token](developer/security/token.md) + * [Authenticating with an NKey](developer/security/nkey.md) + * [Authenticating with a Credentials File](developer/security/creds.md) * [Encrypting Connections with TLS](developer/security/tls.md) * [Receiving Messages](developer/receiving/intro.md) diff --git a/_examples/connect_creds.html b/_examples/connect_creds.html new file mode 100644 index 0000000..c803ecc --- /dev/null +++ b/_examples/connect_creds.html @@ -0,0 +1,41 @@ + +
opt, err := nats.NkeyOptionFromSeed("seed.txt")
+if err != nil {
+ log.Fatal(err)
+}
+nc, err := nats.Connect("localhost", opt)
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+ NKey theNKey = NKey.createUser(null); // really should load from somewhere
+Options options = new Options.Builder().
+ server("nats://localhost:4222").
+ authHandler(new AuthHandler(){
+ public char[] getID() {
+ try {
+ return theNKey.getPublicKey();
+ } catch (GeneralSecurityException|IOException|NullPointerException ex) {
+ return null;
+ }
+ }
+
+ public byte[] sign(byte[] nonce) {
+ try {
+ return theNKey.sign(nonce);
+ } catch (GeneralSecurityException|IOException|NullPointerException ex) {
+ return null;
+ }
+ }
+
+ public char[] getJWT() {
+ return null;
+ }
+ }).
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
+
+digraph nats_request_reply {
+ rankdir=LR
+
+ subgraph {
+ publisher [shape=box, style="rounded", label="Publisher"];
+ }
+
+ subgraph {
+ subject [shape=circle, label="Subject"];
+ reply [shape=circle, label="Reply"];
+ {rank = same subject reply}
+ }
+
+ subgraph {
+ sub1[shape=box, style="rounded", label="Subscriber"];
+ }
+
+ publisher -> subject [label="msg1"];
+ publisher -> reply [style="invis", weight=2];
+ subject -> sub1 [label="msg1"];
+ sub1 -> reply [label="ack"];
+ reply -> publisher;
+}
+
graph nats {
@@ -17,8 +19,4 @@ graph nats {
}
digraph nats_pub_sub {
diff --git a/developer/concepts/queue.md b/developer/concepts/queue.md
index e5617f1..7331ef2 100644
--- a/developer/concepts/queue.md
+++ b/developer/concepts/queue.md
@@ -4,6 +4,8 @@ NATS provides a load balancing feature called queue subscriptions. Using queue s
To create a queue subscription, subscribers register a queue name. All subscribers with the same queue name form the queue group. As messages on the registered subject are published, one member of the group is chosen randomly to receive the message. Although queue groups have multiple subscribers, each message is consumed by only one.
+One of the great features of NATS is that queue groups are defined by the subscribers, not on the server. Applications can create new queue groups without any server change.
+
Queue subscribers are ideal for auto scaling as you can add or remove them anytime, without any configuration changes or restarting the server or clients.
diff --git a/developer/concepts/reqreply.md b/developer/concepts/reqreply.md
index b26ea39..e9f3ac9 100644
--- a/developer/concepts/reqreply.md
+++ b/developer/concepts/reqreply.md
@@ -1,6 +1,6 @@
-# Request Reply
+# Request-Reply and Scatter-Gather
-NATS supports two flavors of request reply messaging: point-to-point or one-to-many. Point-to-point involves the fastest or first to respond. In a one-to-many exchange, you can set a limit on the number of responses the requestor may receive or use a timeout to limit on the speed of the response.
+NATS supports two flavors of request reply messaging: point-to-point or one-to-many. Point-to-point involves the fastest or first to respond. In a one-to-many exchange, you can set a limit on the number of responses the requestor may receive or use a timeout to limit on the speed of the response. One-to-many request reply is sometimes called *scatter gather*.
In a request-response exchange the publish request operation publishes a message with a reply subject expecting a response on that reply subject. Many libraries allow you to use a function that will automatically wait for a response with a timeout. You can also handle that waiting process yourself.
diff --git a/developer/concepts/seq_num.md b/developer/concepts/seq_num.md
new file mode 100644
index 0000000..81501c9
--- /dev/null
+++ b/developer/concepts/seq_num.md
@@ -0,0 +1,25 @@
+# Sequence Numbers
+
+A common problem for one-to-many messages is that a message can get lost or dropped due to a network failure. A simple pattern for resolving this situation is to include a sequence id with the message. Receivers can check the sequence id to see if they miss anything.
+
+
+digraph nats_pub_sub {
+ rankdir=LR
+ publisher [shape=box, style="rounded", label="Publisher"];
+ subject [shape=circle, label="Subject"];
+ sub [shape=box, style="rounded", label="Subscriber"];
+
+ publisher -> subject [label="updates.1"];
+ publisher -> subject [label="updates.2"];
+ publisher -> subject [label="updates.3"];
+
+ subject -> sub [label="updates.*"];
+}
+
+
+In order to really leverage sequence ids there are a few things to keep in mind:
+
+* Each sender will have to use their own sequence
+* If possible, receivers should be able to ask for missing messages by id
+
+With NATS you can embed sequence ids in the message, or you can include them in the subject. For example, a sender can send messages to `updates.1`, `updates.2`, etc... and the subscribers can listen to `updates.*` and optionally parse the subject to determine the sequence id.
\ No newline at end of file
diff --git a/developer/concepts/subjects.md b/developer/concepts/subjects.md
index 1c4323e..1fe94f0 100644
--- a/developer/concepts/subjects.md
+++ b/developer/concepts/subjects.md
@@ -73,3 +73,7 @@ digraph g {
subject -> sub3 [label="msg"];
}
+
+### Monitoring and Wire Taps
+
+Subject to your security configuration, wildcards can be used for monitoring by creating something sometimes called a *wire tap*. In the simplest case you can create a subscriber for `>`. This application will receive all messages, again subject to security settings, sent on your NATS cluster.
\ No newline at end of file
diff --git a/developer/security/creds.md b/developer/security/creds.md
new file mode 100644
index 0000000..aa46b88
--- /dev/null
+++ b/developer/security/creds.md
@@ -0,0 +1,23 @@
+# Authenticating with User Credentials File
+
+The 2.0 version of NATS server introduced the idea of JWT-based authentication. Clients interact with this new scheme using a user JWT and the private key from an NKey pair. To help make connecting with a JWT easier, the client libraries support the concept of a credentials file. This file contains both the private key and the JWT and can be generated with the `nsc` tool. The contents will look like the following and should be protected because it contains a private key. This creds file is unused and only for example purposes.
+
+```ascii
+-----BEGIN NATS USER JWT-----
+eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJUVlNNTEtTWkJBN01VWDNYQUxNUVQzTjRISUw1UkZGQU9YNUtaUFhEU0oyWlAzNkVMNVJBIiwiaWF0IjoxNTU4MDQ1NTYyLCJpc3MiOiJBQlZTQk0zVTQ1REdZRVVFQ0tYUVM3QkVOSFdHN0tGUVVEUlRFSEFKQVNPUlBWV0JaNEhPSUtDSCIsIm5hbWUiOiJvbWVnYSIsInN1YiI6IlVEWEIyVk1MWFBBU0FKN1pEVEtZTlE3UU9DRldTR0I0Rk9NWVFRMjVIUVdTQUY3WlFKRUJTUVNXIiwidHlwZSI6InVzZXIiLCJuYXRzIjp7InB1YiI6e30sInN1YiI6e319fQ.6TQ2ilCDb6m2ZDiJuj_D_OePGXFyN3Ap2DEm3ipcU5AhrWrNvneJryWrpgi_yuVWKo1UoD5s8bxlmwypWVGFAA
+------END NATS USER JWT------
+
+************************* IMPORTANT *************************
+NKEY Seed printed below can be used to sign and prove identity.
+NKEYs are sensitive and should be treated as secrets.
+
+-----BEGIN USER NKEY SEED-----
+SUAOY5JZ2WJKVR4UO2KJ2P3SW6FZFNWEOIMAXF4WZEUNVQXXUOKGM55CYE
+------END USER NKEY SEED------
+
+*************************************************************
+```
+
+Given a creds file, a client can authenticate as a specific user belonging to a specific account:
+
+!INCLUDE "../../_examples/connect_creds.html"
\ No newline at end of file
diff --git a/developer/security/nkey.md b/developer/security/nkey.md
new file mode 100644
index 0000000..5391f1a
--- /dev/null
+++ b/developer/security/nkey.md
@@ -0,0 +1,7 @@
+# Authenticating with an NKey
+
+The 2.0 version of NATS server introduces a new challenge response authentication option. This challenge response is based on a wrapper we call NKeys which uses ED25519 signing. The server can use these keys in several ways for authentication. The simplest is for the server to be configured with a list of known public keys and for the clients to respond to the challenge by signing it with its private key. This challenge-response insures security by insuring that the client has the private key, but also protects the private key from the server which never has to actually see it.
+
+Handling challenge response may require more than just a setting in the connection options, depending on the client library.
+
+!INCLUDE "../../_examples/connect_nkey.html"
\ No newline at end of file