Repository: nats-io/nats.go
Pull request #753 (2021-06-17 21:52:59)

Add Domain to js.AccountInfo() response
Also includes test for #750.


Patch:
diff --git a/js.go b/js.go
index f4b532b..a3fa70f 100644
--- a/js.go
+++ b/js.go
@@ -35,6 +35,9 @@ const (
 	// defaultAPIPrefix is the default prefix for the JetStream API.
 	defaultAPIPrefix = "$JS.API."
 
+	// jsDomainT is used to create JetStream API prefix by specifying only Domain
+	jsDomainT = "$JS.%s.API."
+
 	// apiAccountInfo is for obtaining general information about JetStream.
 	apiAccountInfo = "INFO"
 
@@ -200,6 +203,11 @@ func (opt jsOptFn) configureJSContext(opts *jsOpts) error {
 	return opt(opts)
 }
 
+// Domain changes the domain part of JetSteam API prefix.
+func Domain(domain string) JSOpt {
+	return APIPrefix(fmt.Sprintf(jsDomainT, domain))
+}
+
 // APIPrefix changes the default prefix used for the JetStream API.
 func APIPrefix(pre string) JSOpt {
 	return jsOptFn(func(js *jsOpts) error {
diff --git a/jsm.go b/jsm.go
index 4d5457d..e485ae1 100644
--- a/jsm.go
+++ b/jsm.go
@@ -146,6 +146,7 @@ type AccountInfo struct {
 	Store     uint64        `json:"storage"`
 	Streams   int           `json:"streams"`
 	Consumers int           `json:"consumers"`
+	Domain    string        `json:"domain"`
 	API       APIStats      `json:"api"`
 	Limits    AccountLimits `json:"limits"`
 }


Test patch:
diff --git a/go_test.mod b/go_test.mod
index cac99a7..3c47e81 100644
--- a/go_test.mod
+++ b/go_test.mod
@@ -4,7 +4,7 @@ go 1.15
 
 require (
 	github.com/golang/protobuf v1.4.2
-	github.com/nats-io/nats-server/v2 v2.2.6
+	github.com/nats-io/nats-server/v2 v2.2.7-0.20210618192106-93a3720475a4
 	github.com/nats-io/nkeys v0.3.0
 	github.com/nats-io/nuid v1.0.1
 	google.golang.org/protobuf v1.23.0
diff --git a/go_test.sum b/go_test.sum
index 2ce2e60..0955063 100644
--- a/go_test.sum
+++ b/go_test.sum
@@ -19,6 +19,10 @@ github.com/nats-io/jwt/v2 v2.0.2 h1:ejVCLO8gu6/4bOKIHQpmB5UhhUJfAQw55yvLWpfmKjI=
 github.com/nats-io/jwt/v2 v2.0.2/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY=
 github.com/nats-io/nats-server/v2 v2.2.6 h1:FPK9wWx9pagxcw14s8W9rlfzfyHm61uNLnJyybZbn48=
 github.com/nats-io/nats-server/v2 v2.2.6/go.mod h1:sEnFaxqe09cDmfMgACxZbziXnhQFhwk+aKkZjBBRYrI=
+github.com/nats-io/nats-server/v2 v2.2.7-0.20210615172038-0069f752b61b h1:hy5rgG4Hur55cWBKxD/VbkjaRYYAxo5Ayk9AxGJcHTs=
+github.com/nats-io/nats-server/v2 v2.2.7-0.20210615172038-0069f752b61b/go.mod h1:hBgcnXvNESvh65J1nMtxaHHsaUxSmteZXCH1JLTuvfg=
+github.com/nats-io/nats-server/v2 v2.2.7-0.20210618192106-93a3720475a4 h1:8QM5O7j1a9SdEPzzpQj7daRu4fi/sxfXRxfcKGa5Dr0=
+github.com/nats-io/nats-server/v2 v2.2.7-0.20210618192106-93a3720475a4/go.mod h1:hBgcnXvNESvh65J1nMtxaHHsaUxSmteZXCH1JLTuvfg=
 github.com/nats-io/nats.go v1.11.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
 github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
 github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
@@ -29,6 +33,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b h1:wSOdpTq0/eI46Ez/LkDwIsAKA71YP2SRKBODiRWM0as=
 golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210505212654-3497b51f5e64 h1:QuAh/1Gwc0d+u9walMU1NqzhRemNegsv5esp2ALQIY4=
+golang.org/x/crypto v0.0.0-20210505212654-3497b51f5e64/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
diff --git a/test/js_test.go b/test/js_test.go
index 87b2b32..a9367f6 100644
--- a/test/js_test.go
+++ b/test/js_test.go
@@ -1693,14 +1693,26 @@ func TestAckForNonJetStream(t *testing.T) {
 }
 
 func TestJetStreamManagement(t *testing.T) {
-	s := RunBasicJetStreamServer()
+	conf := createConfFile(t, []byte(`
+                listen: 127.0.0.1:-1
+                jetstream: enabled
+                accounts: {
+                  A {
+                    users: [{ user: "foo" }]
+                    jetstream: { max_mem: 64MB, max_file: 64MB }
+                  }
+                }
+	`))
+	defer os.Remove(conf)
+
+	s, _ := RunServerWithConfig(conf)
 	defer s.Shutdown()
 
 	if config := s.JetStreamConfig(); config != nil {
 		defer os.RemoveAll(config.StoreDir)
 	}
 
-	nc, err := nats.Connect(s.ClientURL())
+	nc, err := nats.Connect(s.ClientURL(), nats.UserInfo("foo", ""))
 	if err != nil {
 		t.Fatalf("Unexpected error: %v", err)
 	}
@@ -1881,10 +1893,10 @@ func TestJetStreamManagement(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		if info.Limits.MaxMemory < 1 {
+		if info.Limits.MaxMemory != 67108864 {
 			t.Errorf("Expected to have memory limits, got: %v", info.Limits.MaxMemory)
 		}
-		if info.Limits.MaxStore < 1 {
+		if info.Limits.MaxStore != 67108864 {
 			t.Errorf("Expected to have disk limits, got: %v", info.Limits.MaxMemory)
 		}
 		if info.Limits.MaxStreams != -1 {
@@ -6188,3 +6200,109 @@ func TestJetStreamBindConsumer(t *testing.T) {
 		t.Fatal(err)
 	}
 }
+
+func TestJetStreamDomain(t *testing.T) {
+	conf := createConfFile(t, []byte(`
+		listen: 127.0.0.1:-1
+		jetstream: { domain: ABC }
+	`))
+	defer os.Remove(conf)
+
+	s, _ := RunServerWithConfig(conf)
+	defer s.Shutdown()
+
+	if config := s.JetStreamConfig(); config != nil {
+		defer os.RemoveAll(config.StoreDir)
+	}
+
+	nc, err := nats.Connect(s.ClientURL())
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+	defer nc.Close()
+
+	// JS with custom domain
+	jsd, err := nc.JetStream(nats.Domain("ABC"))
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+	info, err := jsd.AccountInfo()
+	if err != nil {
+		t.Error(err)
+	}
+	got := info.Domain
+	expected := "ABC"
+	if got != expected {
+		t.Errorf("Got %v, expected: %v", got, expected)
+	}
+
+	if _, err = jsd.AddStream(&nats.StreamConfig{Name: "foo"}); err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+	jsd.Publish("foo", []byte("first"))
+
+	sub, err := jsd.SubscribeSync("foo")
+	if err != nil {
+		t.Fatal(err)
+	}
+	msg, err := sub.NextMsg(time.Second)
+	if err != nil {
+		t.Fatal(err)
+	}
+	got = string(msg.Data)
+	expected = "first"
+	if got != expected {
+		t.Errorf("Got %v, expected: %v", got, expected)
+	}
+
+	// JS without explicit bound domain should also work.
+	js, err := nc.JetStream()
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+	info, err = js.AccountInfo()
+	if err != nil {
+		t.Error(err)
+	}
+	got = info.Domain
+	expected = "ABC"
+	if got != expected {
+		t.Errorf("Got %v, expected: %v", got, expected)
+	}
+
+	js.Publish("foo", []byte("second"))
+
+	sub2, err := js.SubscribeSync("foo")
+	if err != nil {
+		t.Fatal(err)
+	}
+	msg, err = sub2.NextMsg(time.Second)
+	if err != nil {
+		t.Fatal(err)
+	}
+	got = string(msg.Data)
+	expected = "first"
+	if got != expected {
+		t.Errorf("Got %v, expected: %v", got, expected)
+	}
+
+	msg, err = sub2.NextMsg(time.Second)
+	if err != nil {
+		t.Fatal(err)
+	}
+	got = string(msg.Data)
+	expected = "second"
+	if got != expected {
+		t.Errorf("Got %v, expected: %v", got, expected)
+	}
+
+	// Using different domain not configured is an error.
+	jsb, err := nc.JetStream(nats.Domain("XYZ"))
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+	_, err = jsb.AccountInfo()
+	if err != nats.ErrJetStreamNotEnabled {
+		t.Errorf("Unexpected error: %v", err)
+	}
+}