Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Commit

Permalink
SDI-1725:issue1234: RFC: Arbitrary namespace separator
Browse files Browse the repository at this point in the history
  • Loading branch information
candysmurf committed Oct 7, 2016
1 parent 549cf59 commit f8a9910
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 3 deletions.
39 changes: 38 additions & 1 deletion core/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ limitations under the License.
package core

import (
"fmt"
"strings"
"time"

Expand All @@ -31,6 +32,7 @@ var (
// Standard Tags are in added to the metric by the framework on plugin load.
// STD_TAG_PLUGIN_RUNNING_ON describes where the plugin is running (hostname).
STD_TAG_PLUGIN_RUNNING_ON = "plugin_running_on"
nsPriorityList = []string{"/", "|", "%", ":", "-", ";", "_", "^", ">", "<", "+", "=", "&", "㊽", "Ä", "大", "小", "ᵹ", "☍", "ヒ"}
)

// Metric represents a snap metric collected or to be collected
Expand All @@ -51,7 +53,8 @@ type Namespace []NamespaceElement
// the elements of the namespace. A leading "/" is added.
func (n Namespace) String() string {
ns := n.Strings()
return "/" + strings.Join(ns, "/")
s := n.getSeparator()
return s + strings.Join(ns, s)
}

// Strings returns an array of strings that represent the elements of the
Expand All @@ -64,6 +67,40 @@ func (n Namespace) Strings() []string {
return ns
}

// getSeparator returns the highest suitable separator from the nsPriorityList.
// Otherwise the core separator is returned.
func (n Namespace) getSeparator() string {
smap := initSeparatorMap()

for _, e := range n {
// look at each char
for _, r := range e.Value {
ch := fmt.Sprintf("%c", r)
if v, ok := smap[ch]; ok && !v {
smap[ch] = true
}
}
}

// Go through our separator list
for _, s := range nsPriorityList {
if v, ok := smap[s]; ok && !v {
return s
}
}
return Separator
}

// initSeparatorMap populates the local map of nsPriorityList.
func initSeparatorMap() map[string]bool {
m := map[string]bool{}

for _, s := range nsPriorityList {
m[s] = false
}
return m
}

// IsDynamic returns true if there is any element of the namespace which is
// dynamic. If the namespace is dynamic the second return value will contain
// an array of namespace elements (indexes) where there are dynamic namespace
Expand Down
64 changes: 64 additions & 0 deletions core/metric_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// +build small

package core

import (
"fmt"
"testing"

. "github.com/smartystreets/goconvey/convey"
)

func TestMetricSeparator(t *testing.T) {
tc := getTestCases()
Convey("Test namespace separator", t, func() {
for _, c := range tc {
Convey("namespace "+c.input.String(), func() {
firstChar := getFirstChar(c.input.String())
So(firstChar, ShouldEqual, c.expected)
})
}
})
}

// GetFirstChar returns the first character from the input string.
func getFirstChar(s string) string {
firstChar := ""
for _, r := range s {
firstChar = fmt.Sprintf("%c", r)
break
}
return firstChar
}

type testCase struct {
input Namespace
expected string
}

// getTestCases tests the namespace and nsPriorityList.
func getTestCases() []testCase {
tcs := []testCase{
testCase{
input: NewNamespace("/hello", "/world"),
expected: "|",
},
testCase{
input: NewNamespace("/hello", "/world", "corporate-service|"),
expected: "%",
},
testCase{
input: NewNamespace("/hello", "/world", "|corporate-service%", "monday_to_friday"),
expected: ":",
},
testCase{
input: NewNamespace("/hello", "/world", "corporate-service/%|-_^><+=:;&", "monday_friday", "㊽ÄA小ヒ☍"),
expected: "大",
},
testCase{
input: NewNamespace("A小ヒ☍小㊽%:;", "/hello", "/world大|", "monday_friday", "corporate-service"),
expected: "^",
},
}
return tcs
}
35 changes: 35 additions & 0 deletions scheduler/wmap/sample/2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"collect": {
"metrics": {
"㊽foo㊽bar": {
"version": 1
},
"大foo大baz": {},
"/a0/b0": {},
"-a1-b1": {},
"_a2_b2": {},
"㊽a3㊽b3": {},
"Äa4Äb4": {},
"大a5大b5": {},
"小a6小b6": {},
"ᵹa7ᵹb7": {},
"☍a8☍b8": {},
"ヒa9ヒb9": {}
},
"config": {
"%foo%bar": {
"password": "drowssap",
"user": "root"
}
},
"tags": {
"㊽foo㊽bar": {
"tag1": "val1",
"tag2": "val2"
},
"大foo大baz": {
"tag3": "val3"
}
}
}
}
17 changes: 15 additions & 2 deletions scheduler/wmap/wmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,16 +215,29 @@ func (c *CollectWorkflowMapNode) GetMetrics() []Metric {
metrics := make([]Metric, len(c.Metrics))
i := 0
for k, v := range c.Metrics {
ns := strings.Trim(k, `/`)
// Identify the character to split on by peaking
// at the first character of each metric.
firstChar := getFirstChar(k)
ns := strings.Trim(k, firstChar)
metrics[i] = Metric{
namespace: strings.Split(ns, "/"),
namespace: strings.Split(ns, firstChar),
version: v.Version_,
}
i++
}
return metrics
}

// GetFirstChar returns the first character from the input string.
func getFirstChar(s string) string {
firstChar := ""
for _, r := range s {
firstChar = fmt.Sprintf("%c", r)
break
}
return firstChar
}

func (c *CollectWorkflowMapNode) GetTags() map[string]map[string]string {
return c.Tags
}
Expand Down
21 changes: 21 additions & 0 deletions scheduler/wmap/wmap_small_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ limitations under the License.
package wmap

import (
"io/ioutil"
"strconv"
"testing"

. "github.com/smartystreets/goconvey/convey"
Expand Down Expand Up @@ -223,3 +225,22 @@ func TestStringByteConvertion(t *testing.T) {
So(err, ShouldNotBeNil)
})
}

func TestMetricSeparator(t *testing.T) {
jsonP, _ := ioutil.ReadFile("./sample/2.json")

Convey("Get Metric", t, func() {
Convey("from json", func() {
wmap, err := FromJson(jsonP)
So(err, ShouldBeNil)
So(wmap, ShouldNotBeNil)

mts := wmap.CollectNode.GetMetrics()
for i, m := range mts {
Convey("namespace "+strconv.Itoa(i), func() {
So(len(m.Namespace()), ShouldEqual, 2)
})
}
})
})
}

0 comments on commit f8a9910

Please sign in to comment.