SDL CLI 'get namespaces' -command key count 28/7128/2
authorTimo Tietavainen <timo.tietavainen@nokia.com>
Thu, 25 Nov 2021 22:57:59 +0000 (00:57 +0200)
committerTimo Tietavainen <timo.tietavainen@nokia.com>
Fri, 26 Nov 2021 14:24:08 +0000 (16:24 +0200)
Change existing -g,--group flag to -w,--wide flag. When the flag has
been set, command shows DB namespaces per SDL cluster group address
and how many DB keys there are per namespace.
New command syntax is:
    sdlcli get namespaces [flags]
Where supported flags are: -w, --wide, -h and --help.

Issue-Id: RIC-113

Signed-off-by: Timo Tietavainen <timo.tietavainen@nokia.com>
Change-Id: Iae0b044257a5e26e6cfaa48e2a5dca8441c23d5c

internal/cli/namespaces.go
internal/cli/namespaces_test.go
internal/cli/types.go

index 9cf5ee8..d8c73ee 100644 (file)
@@ -28,6 +28,7 @@ import (
        "os"
        "sort"
        "strings"
+       "text/tabwriter"
 )
 
 func init() {
@@ -41,14 +42,14 @@ func newNamespacesCmd(dbCreateCb DbCreateCb) *cobra.Command {
                Long:  "List all the namespaces in database",
                Args:  cobra.ExactArgs(0),
                RunE: func(cmd *cobra.Command, args []string) error {
-                       showPerDb, _ := cmd.Flags().GetBool("group")
+                       showWide, _ := cmd.Flags().GetBool("wide")
                        nsMap, err := runNamespaces(dbCreateCb)
                        if err != nil {
                                cmd.PrintErrf("%s\n", buf.String())
                                return err
                        }
-                       if showPerDb {
-                               printNamespacesPerDb(cmd, nsMap)
+                       if showWide {
+                               printNamespacesWide(cmd, nsMap)
                        } else {
                                printNamespaces(cmd, nsMap)
                        }
@@ -56,12 +57,12 @@ func newNamespacesCmd(dbCreateCb DbCreateCb) *cobra.Command {
                },
        }
        cmd.SetOut(os.Stdout)
-       cmd.Flags().BoolP("group", "g", false, "Show namespaces per SDL DB cluster group")
+       cmd.Flags().BoolP("wide", "w", false, "Show SDL DB cluster address, namespace name and its keys count")
        return cmd
 }
 
-func runNamespaces(dbCreateCb DbCreateCb) (map[string][]string, error) {
-       nsMap := make(map[string][]string)
+func runNamespaces(dbCreateCb DbCreateCb) (nsMap, error) {
+       nsMap := make(nsMap)
        for _, dbInst := range dbCreateCb().Instances {
                keys, err := dbInst.Keys("*")
                if err != nil {
@@ -71,13 +72,20 @@ func runNamespaces(dbCreateCb DbCreateCb) (map[string][]string, error) {
                if err != nil {
                        return nil, err
                }
+
+               if _, ok := nsMap[id]; !ok {
+                       nsMap[id] = make(nsKeyMap)
+               }
+
                for _, key := range keys {
                        namespace, err := parseKeyNamespace(key)
                        if err != nil {
                                return nil, err
                        }
                        if isUniqueNamespace(nsMap[id], namespace) {
-                               nsMap[id] = append(nsMap[id], namespace)
+                               nsMap[id][namespace] = 1
+                       } else {
+                               nsMap[id][namespace]++
                        }
                }
        }
@@ -105,36 +113,44 @@ func parseKeyNamespace(key string) (string, error) {
        return str[:eIndex], nil
 }
 
-func isUniqueNamespace(namespaces []string, newNs string) bool {
-       for _, n := range namespaces {
-               if n == newNs {
-                       return false
-               }
+func isUniqueNamespace(namespaces nsKeyMap, newNs string) bool {
+       if _, ok := namespaces[newNs]; ok {
+               return false
        }
        return true
 }
 
-func printNamespaces(cmd *cobra.Command, nsMap map[string][]string) {
-       var namespaces []string
-       for _, nsList := range nsMap {
-               namespaces = append(namespaces, nsList...)
+func printNamespaces(cmd *cobra.Command, nsMap nsMap) {
+       var nsList []string
+       for _, nsKeyMap := range nsMap {
+               for ns, _ := range nsKeyMap {
+                       nsList = append(nsList, ns)
+               }
        }
 
-       sort.Strings(namespaces)
-       for _, ns := range namespaces {
+       sort.Strings(nsList)
+       for _, ns := range nsList {
                cmd.Println(ns)
        }
 }
 
-func printNamespacesPerDb(cmd *cobra.Command, nsMap map[string][]string) {
-       for addr, nsList := range nsMap {
+func printNamespacesWide(cmd *cobra.Command, nsMap nsMap) {
+       var nsList []string
+       w := tabwriter.NewWriter(cmd.OutOrStdout(), 6, 4, 3, ' ', 0)
+       fmt.Fprintln(w, "ADDRESS\tNAMESPACE\tKEYS\t")
+       for addr, nsKeyMap := range nsMap {
+               for ns, _ := range nsKeyMap {
+                       nsList = append(nsList, ns)
+               }
                sort.Strings(nsList)
                for _, ns := range nsList {
                        if addr == "" {
-                               cmd.Printf("%s\n", ns)
+                               fmt.Fprintf(w, "\t%s\t%d\t\n", ns, nsKeyMap[ns])
                        } else {
-                               cmd.Printf("%s: %s\n", addr, ns)
+                               fmt.Fprintf(w, "%s\t%s\t%d\t\n", addr, ns, nsKeyMap[ns])
                        }
                }
+               nsList = nil
        }
+       w.Flush()
 }
index 28b6343..65bec5f 100644 (file)
@@ -112,8 +112,12 @@ func TestNamespacesCmdSuccess(t *testing.T) {
        mNs.dbIface.AssertExpectations(t)
 }
 
-func TestNamespacesCmdWithPerDbFlagSuccess(t *testing.T) {
-       expOut := "1.2.3.4:6379: ns1\n" + "1.2.3.4:6379: ns2\n" + "1.2.3.4:6379: ns3\n"
+func TestNamespacesCmdWithWideFlagSuccess(t *testing.T) {
+       expOut :=
+               "ADDRESS        NAMESPACE   KEYS   \n" +
+                       "1.2.3.4:6379   ns1         2      \n" +
+                       "1.2.3.4:6379   ns2         1      \n" +
+                       "1.2.3.4:6379   ns3         1      \n"
        buf := new(bytes.Buffer)
        setupNamespacesCliMock([]string{
                "{ns1},key1",
@@ -124,7 +128,7 @@ func TestNamespacesCmdWithPerDbFlagSuccess(t *testing.T) {
        cmd := cli.NewNamespacesCmdForTest(newNsMockDatabase)
        cmd.SetOut(buf)
        cmd.SetErr(buf)
-       cmd.SetArgs([]string{"--group"})
+       cmd.SetArgs([]string{"--wide"})
 
        err := cmd.Execute()
        result := buf.String()
@@ -150,14 +154,14 @@ func TestNamespacesCmdNoKeysInDbSuccess(t *testing.T) {
        mNs.dbIface.AssertExpectations(t)
 }
 
-func TestNamespacesCmdWithPerDbFlagNoKeysInDbSuccess(t *testing.T) {
-       expOut := ""
+func TestNamespacesCmdWithWideFlagNoKeysInDbSuccess(t *testing.T) {
+       expOut := "ADDRESS   NAMESPACE   KEYS   \n"
        buf := new(bytes.Buffer)
        setupNamespacesCliMock([]string{}, "1.2.3.4", nil, nil)
        cmd := cli.NewNamespacesCmdForTest(newNsMockDatabase)
        cmd.SetOut(buf)
        cmd.SetErr(buf)
-       cmd.SetArgs([]string{"--group"})
+       cmd.SetArgs([]string{"-w"})
 
        err := cmd.Execute()
        result := buf.String()
@@ -167,8 +171,12 @@ func TestNamespacesCmdWithPerDbFlagNoKeysInDbSuccess(t *testing.T) {
        mNs.dbIface.AssertExpectations(t)
 }
 
-func TestNamespacesCmdWithPerDbFlagStandaloneRedisAddressMissingSuccess(t *testing.T) {
-       expOut := "ns1\n" + "ns2\n" + "ns3\n"
+func TestNamespacesCmdWithWideFlagStandaloneRedisAddressMissingSuccess(t *testing.T) {
+       expOut :=
+               "ADDRESS   NAMESPACE   KEYS   \n" +
+                       "          ns1         2      \n" +
+                       "          ns2         1      \n" +
+                       "          ns3         1      \n"
        buf := new(bytes.Buffer)
        setupNamespacesCliMock([]string{
                "{ns1},key1",
@@ -179,7 +187,7 @@ func TestNamespacesCmdWithPerDbFlagStandaloneRedisAddressMissingSuccess(t *testi
        cmd := cli.NewNamespacesCmdForTest(newNsMockDatabase)
        cmd.SetOut(buf)
        cmd.SetErr(buf)
-       cmd.SetArgs([]string{"--group"})
+       cmd.SetArgs([]string{"--wide"})
 
        err := cmd.Execute()
        result := buf.String()
index f5c4439..eb86905 100644 (file)
@@ -65,5 +65,11 @@ func newKeysArgs(ns string, pattern string) keysArgs {
        }
 }
 
+//nsMap is a map having SDL DB cluster address as a key and namespace map of type nsKeyMap as a value
+type nsMap map[string]nsKeyMap
+
+//nsKeyMap is a map having namespace as a key and DB key count as a value
+type nsKeyMap map[string]uint32
+
 //SdlCliApp constant defines the name of the SDL CLI application
 const SdlCliApp = "sdlcli"