Skip to content

Commit

Permalink
add models for dependencies.go, hash.go, keyvalue.go, process.go (#123)
Browse files Browse the repository at this point in the history
## Which problem is this PR solving?
[#6571](jaegertracing/jaeger#6571)

## Description of the changes
- Copy set of types from original `model/` -> `dependencies.go`,
`hash.go`, `keyvalue.go`, `process.go`

## How was this change tested?
- `go test ./model/v1`

## Checklist
- [x] I have read
https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md
- [x] I have signed all commits
- [x] I have added unit tests for the new functionality
- [x] I have run lint and test steps successfully
  - for lint: `golangci-lint run  ./model/v1/`
  - for tests: `go test ./model/v1`

---------

Signed-off-by: nabil salah <nabil.salah203@gmail.com>
Signed-off-by: Yuri Shkuro <yurishkuro@users.noreply.github.com>
Co-authored-by: Yuri Shkuro <yurishkuro@users.noreply.github.com>
  • Loading branch information
Nabil-Salah and yurishkuro authored Jan 21, 2025
1 parent 18f62b1 commit 2c9caf2
Show file tree
Hide file tree
Showing 9 changed files with 804 additions and 0 deletions.
19 changes: 19 additions & 0 deletions model/v1/dependencies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2019 The Jaeger Authors.
// Copyright (c) 2017 Uber Technologies, Inc.
// SPDX-License-Identifier: Apache-2.0

package model

const (
// JaegerDependencyLinkSource describes a dependency diagram that was generated from Jaeger traces.
JaegerDependencyLinkSource = "jaeger"
)

// ApplyDefaults applies defaults to the DependencyLink.
func (d DependencyLink) ApplyDefaults() DependencyLink {
dd := d
if dd.Source == "" {
dd.Source = JaegerDependencyLinkSource
}
return dd
}
19 changes: 19 additions & 0 deletions model/v1/dependencies_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2019 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package model

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestDependencyLinkApplyDefaults(t *testing.T) {
dl := DependencyLink{}.ApplyDefaults()
assert.Equal(t, JaegerDependencyLinkSource, dl.Source)

networkSource := "network"
dl = DependencyLink{Source: networkSource}.ApplyDefaults()
assert.Equal(t, networkSource, dl.Source)
}
25 changes: 25 additions & 0 deletions model/v1/hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2019 The Jaeger Authors.
// Copyright (c) 2017 Uber Technologies, Inc.
// SPDX-License-Identifier: Apache-2.0

package model

import (
"hash/fnv"
"io"
)

// Hashable interface is for type that can participate in a hash computation
// by writing their data into io.Writer, which is usually an instance of hash.Hash.
type Hashable interface {
Hash(w io.Writer) error
}

// HashCode calculates a FNV-1a hash code for a Hashable object.
func HashCode(o Hashable) (uint64, error) {
h := fnv.New64a()
if err := o.Hash(h); err != nil {
return 0, err
}
return h.Sum64(), nil
}
49 changes: 49 additions & 0 deletions model/v1/hash_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2019 The Jaeger Authors.
// Copyright (c) 2017 Uber Technologies, Inc.
// SPDX-License-Identifier: Apache-2.0

package model_test

import (
"errors"
"fmt"
"io"
"testing"

"github.com/jaegertracing/jaeger-idl/model/v1"
"github.com/stretchr/testify/assert"
)

type mockHashWwiterAnswer struct {
n int
err error
}

type mockHashWwiter struct {
answers []mockHashWwiterAnswer
}

func (w *mockHashWwiter) Write(data []byte) (int, error) {
if len(w.answers) == 0 {
return 0, fmt.Errorf("no answer registered for call with data=%+v", data)
}
answer := w.answers[0]
w.answers = w.answers[1:]
return answer.n, answer.err
}

type errHashable struct {
err error
}

func (e *errHashable) Hash(io.Writer) error {
return e.err
}

func TestHasCodeError(t *testing.T) {
someErr := errors.New("some error")
h := &errHashable{err: someErr}
n, err := model.HashCode(h)
assert.Equal(t, uint64(0), n)
assert.Equal(t, someErr, err)
}
246 changes: 246 additions & 0 deletions model/v1/keyvalue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
// Copyright (c) 2019 The Jaeger Authors.
// Copyright (c) 2017 Uber Technologies, Inc.
// SPDX-License-Identifier: Apache-2.0

package model

import (
"encoding/binary"
"encoding/hex"
"fmt"
"io"
"sort"
"strconv"
)

// These constants are kept mostly for backwards compatibility.
const (
// StringType indicates the value is a unicode string
StringType = ValueType_STRING
// BoolType indicates the value is a Boolean encoded as int64 number 0 or 1
BoolType = ValueType_BOOL
// Int64Type indicates the value is an int64 number
Int64Type = ValueType_INT64
// Float64Type indicates the value is a float64 number stored as int64
Float64Type = ValueType_FLOAT64
// BinaryType indicates the value is binary blob stored as a byte array
BinaryType = ValueType_BINARY

SpanKindKey = "span.kind"
SamplerTypeKey = "sampler.type"
SamplerParamKey = "sampler.param"
)

type SpanKind string

const (
SpanKindClient SpanKind = "client"
SpanKindServer SpanKind = "server"
SpanKindProducer SpanKind = "producer"
SpanKindConsumer SpanKind = "consumer"
SpanKindInternal SpanKind = "internal"
SpanKindUnspecified SpanKind = ""
)

func SpanKindFromString(kind string) (SpanKind, error) {
switch SpanKind(kind) {
case SpanKindClient, SpanKindServer, SpanKindProducer, SpanKindConsumer, SpanKindInternal, SpanKindUnspecified:
return SpanKind(kind), nil
default:
return SpanKindUnspecified, fmt.Errorf("unknown span kind %q", kind)
}
}

// KeyValues is a type alias that exposes convenience functions like Sort, FindByKey.
type KeyValues []KeyValue

// String creates a String-typed KeyValue
func String(key string, value string) KeyValue {
return KeyValue{Key: key, VType: StringType, VStr: value}
}

// Bool creates a Bool-typed KeyValue
func Bool(key string, value bool) KeyValue {
return KeyValue{Key: key, VType: BoolType, VBool: value}
}

// Int64 creates a Int64-typed KeyValue
func Int64(key string, value int64) KeyValue {
return KeyValue{Key: key, VType: Int64Type, VInt64: value}
}

// Float64 creates a Float64-typed KeyValue
func Float64(key string, value float64) KeyValue {
return KeyValue{Key: key, VType: Float64Type, VFloat64: value}
}

// Binary creates a Binary-typed KeyValue
func Binary(key string, value []byte) KeyValue {
return KeyValue{Key: key, VType: BinaryType, VBinary: value}
}

// Bool returns the Boolean value stored in this KeyValue or false if it stores a different type.
// The caller must check VType before using this method.
func (kv *KeyValue) Bool() bool {
if kv.VType == BoolType {
return kv.VBool
}
return false
}

// Int64 returns the Int64 value stored in this KeyValue or 0 if it stores a different type.
// The caller must check VType before using this method.
func (kv *KeyValue) Int64() int64 {
if kv.VType == Int64Type {
return kv.VInt64
}
return 0
}

// Float64 returns the Float64 value stored in this KeyValue or 0 if it stores a different type.
// The caller must check VType before using this method.
func (kv *KeyValue) Float64() float64 {
if kv.VType == Float64Type {
return kv.VFloat64
}
return 0
}

// Binary returns the blob ([]byte) value stored in this KeyValue or nil if it stores a different type.
// The caller must check VType before using this method.
func (kv *KeyValue) Binary() []byte {
if kv.VType == BinaryType {
return kv.VBinary
}
return nil
}

// Value returns typed values stored in KeyValue as any.
func (kv *KeyValue) Value() any {
switch kv.VType {
case StringType:
return kv.VStr
case BoolType:
return kv.VBool
case Int64Type:
return kv.VInt64
case Float64Type:
return kv.VFloat64
case BinaryType:
return kv.VBinary
default:
return fmt.Errorf("unknown type %d", kv.VType)
}
}

// AsStringLossy returns a potentially lossy string representation of the value.
func (kv *KeyValue) AsStringLossy() string {
return kv.asString(true)
}

// AsString returns a string representation of the value.
func (kv *KeyValue) AsString() string {
return kv.asString(false)
}

func (kv *KeyValue) asString(truncate bool) string {
switch kv.VType {
case StringType:
return kv.VStr
case BoolType:
if kv.Bool() {
return "true"
}
return "false"
case Int64Type:
return strconv.FormatInt(kv.Int64(), 10)
case Float64Type:
return strconv.FormatFloat(kv.Float64(), 'g', 10, 64)
case BinaryType:
if truncate && len(kv.VBinary) > 256 {
return hex.EncodeToString(kv.VBinary[0:256]) + "..."
}
return hex.EncodeToString(kv.VBinary)
default:
return fmt.Sprintf("unknown type %d", kv.VType)
}
}

// IsLess compares KeyValue object with another KeyValue.
// The order is based first on the keys, then on type, and finally on the value.
func (kv *KeyValue) IsLess(two *KeyValue) bool {
return kv.Compare(two) < 0
}

func (kvs KeyValues) Len() int { return len(kvs) }
func (kvs KeyValues) Swap(i, j int) { kvs[i], kvs[j] = kvs[j], kvs[i] }
func (kvs KeyValues) Less(i, j int) bool {
return kvs[i].IsLess(&kvs[j])
}

// Sort does in-place sorting of KeyValues, then by value type, then by value.
func (kvs KeyValues) Sort() {
sort.Sort(kvs)
}

// FindByKey scans the list of key-values searching for the first one with the given key.
// Returns found tag and a boolean flag indicating if the search was successful.
func (kvs KeyValues) FindByKey(key string) (KeyValue, bool) {
for _, kv := range kvs {
if kv.Key == key {
return kv, true
}
}
return KeyValue{}, false
}

// Equal compares KeyValues with another list. Both lists must be already sorted.
func (kvs KeyValues) Equal(other KeyValues) bool {
l1, l2 := len(kvs), len(other)
if l1 != l2 {
return false
}
for i := 0; i < l1; i++ {
if !kvs[i].Equal(&other[i]) {
return false
}
}
return true
}

// Hash implements Hash from Hashable.
func (kvs KeyValues) Hash(w io.Writer) error {
for i := range kvs {
if err := kvs[i].Hash(w); err != nil {
return err
}
}
return nil
}

// Hash implements Hash from Hashable.
func (kv KeyValue) Hash(w io.Writer) error {
if _, err := w.Write([]byte(kv.Key)); err != nil {
return err
}
//nolint: gosec // G115
if err := binary.Write(w, binary.BigEndian, uint16(kv.VType)); err != nil {
return err
}
var err error
switch kv.VType {
case StringType:
_, err = w.Write([]byte(kv.VStr))
case BoolType:
err = binary.Write(w, binary.BigEndian, kv.VBool)
case Int64Type:
err = binary.Write(w, binary.BigEndian, kv.VInt64)
case Float64Type:
err = binary.Write(w, binary.BigEndian, kv.VFloat64)
case BinaryType:
_, err = w.Write(kv.VBinary)
default:
err = fmt.Errorf("unknown type %d", kv.VType)
}
return err
}
Loading

0 comments on commit 2c9caf2

Please sign in to comment.