Add account details to subsz.

Also allow ability to filter based on account.

Signed-off-by: Derek Collison <derek@nats.io>
This commit is contained in:
Derek Collison
2020-06-05 05:53:01 -07:00
parent 326f6c2e00
commit c1ffd48638
2 changed files with 54 additions and 2 deletions

View File

@@ -139,7 +139,7 @@ const defaultStackBufSize = 10000
func newSubsDetailList(client *client) []SubDetail {
subsDetail := make([]SubDetail, 0, len(client.subs))
for _, sub := range client.subs {
subsDetail = append(subsDetail, newSubDetail(sub))
subsDetail = append(subsDetail, newClientSubDetail(sub))
}
return subsDetail
}
@@ -771,9 +771,12 @@ type SubszOptions struct {
// Limit is the maximum number of subscriptions that should be returned by Subsz().
Limit int `json:"limit"`
// Subscriptions indicates if subscriptions should be included in the results.
// Subscriptions indicates if subscription details should be included in the results.
Subscriptions bool `json:"subscriptions"`
// Filter based on this account name.
Account string `json:"account,omitempty"`
// Test the list against this subject. Needs to be literal since it signifies a publish subject.
// We will only return subscriptions that would match if a message was sent to this subject.
Test string `json:"test,omitempty"`
@@ -781,6 +784,7 @@ type SubszOptions struct {
// SubDetail is for verbose information for subscriptions.
type SubDetail struct {
Account string `json:"account,omitempty"`
Subject string `json:"subject"`
Queue string `json:"qgroup,omitempty"`
Sid string `json:"sid"`
@@ -789,8 +793,10 @@ type SubDetail struct {
Cid uint64 `json:"cid"`
}
// Subscription client should be locked and guaranteed to be present.
func newSubDetail(sub *subscription) SubDetail {
return SubDetail{
Account: sub.client.acc.GetName(),
Subject: string(sub.subject),
Queue: string(sub.queue),
Sid: string(sub.sid),
@@ -800,6 +806,17 @@ func newSubDetail(sub *subscription) SubDetail {
}
}
// For subs details under clients.
func newClientSubDetail(sub *subscription) SubDetail {
return SubDetail{
Subject: string(sub.subject),
Queue: string(sub.queue),
Sid: string(sub.sid),
Msgs: sub.nm,
Max: sub.max,
}
}
// Subsz returns a Subsz struct containing subjects statistics
func (s *Server) Subsz(opts *SubszOptions) (*Subsz, error) {
var (
@@ -808,6 +825,7 @@ func (s *Server) Subsz(opts *SubszOptions) (*Subsz, error) {
offset int
limit = DefaultSubListSize
testSub = ""
filterAcc = ""
)
if opts != nil {
@@ -827,6 +845,9 @@ func (s *Server) Subsz(opts *SubszOptions) (*Subsz, error) {
return nil, fmt.Errorf("invalid test subject, must be valid publish subject: %s", testSub)
}
}
if opts.Account != "" {
filterAcc = opts.Account
}
}
slStats := &SublistStats{}
@@ -839,6 +860,9 @@ func (s *Server) Subsz(opts *SubszOptions) (*Subsz, error) {
subs := raw[:0]
s.accounts.Range(func(k, v interface{}) bool {
acc := v.(*Account)
if filterAcc != "" && acc.GetName() != filterAcc {
return true
}
slStats.add(acc.sl.Stats())
acc.sl.localSubs(&subs)
return true
@@ -877,6 +901,9 @@ func (s *Server) Subsz(opts *SubszOptions) (*Subsz, error) {
} else {
s.accounts.Range(func(k, v interface{}) bool {
acc := v.(*Account)
if filterAcc != "" && acc.GetName() != filterAcc {
return true
}
slStats.add(acc.sl.Stats())
return true
})
@@ -904,11 +931,14 @@ func (s *Server) HandleSubsz(w http.ResponseWriter, r *http.Request) {
return
}
testSub := r.URL.Query().Get("test")
// Filtered account.
filterAcc := r.URL.Query().Get("acc")
subszOpts := &SubszOptions{
Subscriptions: subs,
Offset: offset,
Limit: limit,
Account: filterAcc,
Test: testSub,
}

View File

@@ -1547,6 +1547,28 @@ func TestSubszMultiAccount(t *testing.T) {
if len(sl.Subs) != 6 {
t.Fatalf("Expected subscription details for 6 subs, got %d\n", len(sl.Subs))
}
for _, sd := range sl.Subs {
if sd.Account != "A" && sd.Account != "B" {
t.Fatalf("Expected account information to be present and be 'A' or 'B', got %q", sd.Account)
}
}
// Now make sure we can filter on account.
sl = pollSubsz(t, s, mode, url+"subsz?subs=1&acc=A", &SubszOptions{Account: "A", Subscriptions: true})
if sl.NumSubs != 3 {
t.Fatalf("Expected NumSubs of 3, got %d\n", sl.NumSubs)
}
if sl.Total != 3 {
t.Fatalf("Expected Total of 6, got %d\n", sl.Total)
}
if len(sl.Subs) != 3 {
t.Fatalf("Expected subscription details for 6 subs, got %d\n", len(sl.Subs))
}
for _, sd := range sl.Subs {
if sd.Account != "A" {
t.Fatalf("Expected account information to be present and be 'A', got %q", sd.Account)
}
}
}
}