Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
package(default_visibility = ["//visibility:public"])
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = [
"key.go",
"metadata.go",
],
importpath = "go-common/library/net/metadata",
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["metadata_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = ["//vendor/github.com/stretchr/testify/assert:go_default_library"],
)

View File

@@ -0,0 +1,23 @@
### net/metadata
### Version 1.3.3
1. metadata支持int64
### Version 1.3.2
1. WithContext使用copy 防止panic
### Version 1.3.1
1. key 加入 Device = "device"
### Version 1.3.0
1. 增加WithContext方法
### Version 1.2.0
1. 增加mirror字段
### Version 1.1.0
1. 增加String方法
##### Version 1.0.0
1. 完成基本功能与测试

View File

@@ -0,0 +1,6 @@
# Author
weicheng
zhoujiahui
# Reviewer
maojian

View File

@@ -0,0 +1,9 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- weicheng
- zhoujiahui
reviewers:
- maojian
- weicheng
- zhoujiahui

View File

@@ -0,0 +1,13 @@
#### net/metadata
##### 项目简介
用于储存各种元信息
##### 编译环境
- **请只用 Golang v1.8.x 以上版本编译执行**
##### 依赖包
- No other dependency

View File

@@ -0,0 +1,56 @@
package metadata
// metadata common key
const (
// Network
RemoteIP = "remote_ip"
RemotePort = "remote_port"
ServerAddr = "server_addr"
ClientAddr = "client_addr"
// Router
Color = "color"
// Trace
Trace = "trace"
Caller = "caller"
// Timeout
Timeout = "timeout"
// Dispatch
CPUUsage = "cpu_usage"
Errors = "errors"
Requests = "requests"
// Mirror
Mirror = "mirror"
// Mid
// 外网账户用户id
Mid = "mid"
// Uid
// 内网manager平台的用户id user_id
Uid = "uid"
// Username
// LDAP平台的username
Username = "username"
// Device
Device = "device"
// Cluster cluster info key
Cluster = "cluster"
)

View File

@@ -0,0 +1,134 @@
package metadata
import (
"context"
"fmt"
"strconv"
)
// MD is a mapping from metadata keys to values.
type MD map[string]interface{}
type mdKey struct{}
// Len returns the number of items in md.
func (md MD) Len() int {
return len(md)
}
// Copy returns a copy of md.
func (md MD) Copy() MD {
return Join(md)
}
// New creates an MD from a given key-value map.
func New(m map[string]interface{}) MD {
md := MD{}
for k, val := range m {
md[k] = val
}
return md
}
// Join joins any number of mds into a single MD.
// The order of values for each key is determined by the order in which
// the mds containing those values are presented to Join.
func Join(mds ...MD) MD {
out := MD{}
for _, md := range mds {
for k, v := range md {
out[k] = v
}
}
return out
}
// Pairs returns an MD formed by the mapping of key, value ...
// Pairs panics if len(kv) is odd.
func Pairs(kv ...interface{}) MD {
if len(kv)%2 == 1 {
panic(fmt.Sprintf("metadata: Pairs got the odd number of input pairs for metadata: %d", len(kv)))
}
md := MD{}
var key string
for i, s := range kv {
if i%2 == 0 {
key = s.(string)
continue
}
md[key] = s
}
return md
}
// NewContext creates a new context with md attached.
func NewContext(ctx context.Context, md MD) context.Context {
return context.WithValue(ctx, mdKey{}, md)
}
// FromContext returns the incoming metadata in ctx if it exists. The
// returned MD should not be modified. Writing to it may cause races.
// Modification should be made to copies of the returned MD.
func FromContext(ctx context.Context) (md MD, ok bool) {
md, ok = ctx.Value(mdKey{}).(MD)
return
}
// String get string value from metadata in context
func String(ctx context.Context, key string) string {
md, ok := ctx.Value(mdKey{}).(MD)
if !ok {
return ""
}
str, _ := md[key].(string)
return str
}
// Int64 get int64 value from metadata in context
func Int64(ctx context.Context, key string) int64 {
md, ok := ctx.Value(mdKey{}).(MD)
if !ok {
return 0
}
i64, _ := md[key].(int64)
return i64
}
// Value get value from metadata in context return nil if not found
func Value(ctx context.Context, key string) interface{} {
md, ok := ctx.Value(mdKey{}).(MD)
if !ok {
return nil
}
return md[key]
}
// WithContext return no deadline context and retain metadata.
func WithContext(c context.Context) context.Context {
md, ok := FromContext(c)
if ok {
nmd := md.Copy()
// NOTE: temporary delete prevent asynchronous task reuse finished task
delete(nmd, Trace)
return NewContext(context.Background(), nmd)
}
return context.Background()
}
// Bool get boolean from metadata in context use strconv.Parse.
func Bool(ctx context.Context, key string) bool {
md, ok := ctx.Value(mdKey{}).(MD)
if !ok {
return false
}
switch md[key].(type) {
case bool:
return md[key].(bool)
case string:
ok, _ = strconv.ParseBool(md[key].(string))
return ok
default:
return false
}
}

View File

@@ -0,0 +1,96 @@
package metadata
import (
"context"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPairsMD(t *testing.T) {
for _, test := range []struct {
// input
kv []interface{}
// output
md MD
}{
{[]interface{}{}, MD{}},
{[]interface{}{"k1", "v1", "k1", "v2"}, MD{"k1": "v2"}},
} {
md := Pairs(test.kv...)
if !reflect.DeepEqual(md, test.md) {
t.Fatalf("Pairs(%v) = %v, want %v", test.kv, md, test.md)
}
}
}
func TestCopy(t *testing.T) {
const key, val = "key", "val"
orig := Pairs(key, val)
copy := orig.Copy()
if !reflect.DeepEqual(orig, copy) {
t.Errorf("copied value not equal to the original, got %v, want %v", copy, orig)
}
orig[key] = "foo"
if v := copy[key]; v != val {
t.Errorf("change in original should not affect copy, got %q, want %q", v, val)
}
}
func TestJoin(t *testing.T) {
for _, test := range []struct {
mds []MD
want MD
}{
{[]MD{}, MD{}},
{[]MD{Pairs("foo", "bar")}, Pairs("foo", "bar")},
{[]MD{Pairs("foo", "bar"), Pairs("foo", "baz")}, Pairs("foo", "bar", "foo", "baz")},
{[]MD{Pairs("foo", "bar"), Pairs("foo", "baz"), Pairs("zip", "zap")}, Pairs("foo", "bar", "foo", "baz", "zip", "zap")},
} {
md := Join(test.mds...)
if !reflect.DeepEqual(md, test.want) {
t.Errorf("context's metadata is %v, want %v", md, test.want)
}
}
}
func TestWithContext(t *testing.T) {
md := MD(map[string]interface{}{RemoteIP: "127.0.0.1", Color: "red", Mirror: true})
c := NewContext(context.Background(), md)
ctx := WithContext(c)
md1, ok := FromContext(ctx)
if !ok {
t.Errorf("expect ok be true")
t.FailNow()
}
if !reflect.DeepEqual(md1, md) {
t.Errorf("expect md1 equal to md")
t.FailNow()
}
}
func TestBool(t *testing.T) {
md := MD{RemoteIP: "127.0.0.1", Color: "red"}
mdcontext := NewContext(context.Background(), md)
assert.Equal(t, false, Bool(mdcontext, Mirror))
mdcontext = NewContext(context.Background(), MD{Mirror: true})
assert.Equal(t, true, Bool(mdcontext, Mirror))
mdcontext = NewContext(context.Background(), MD{Mirror: "true"})
assert.Equal(t, true, Bool(mdcontext, Mirror))
mdcontext = NewContext(context.Background(), MD{Mirror: "1"})
assert.Equal(t, true, Bool(mdcontext, Mirror))
mdcontext = NewContext(context.Background(), MD{Mirror: "0"})
assert.Equal(t, false, Bool(mdcontext, Mirror))
}
func TestInt64(t *testing.T) {
mdcontext := NewContext(context.Background(), MD{Uid: int64(1)})
assert.Equal(t, int64(1), Int64(mdcontext, Uid))
mdcontext = NewContext(context.Background(), MD{Uid: int64(2)})
assert.NotEqual(t, int64(1), Int64(mdcontext, Uid))
mdcontext = NewContext(context.Background(), MD{Uid: 10})
assert.NotEqual(t, int64(10), Int64(mdcontext, Uid))
}