forked from newrelic/go-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
txndata.go
99 lines (78 loc) · 2.26 KB
/
txndata.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package cat
import (
"bytes"
"encoding/json"
"errors"
"github.com/newrelic/go-agent/internal/jsonx"
)
// TxnDataHeader represents a decoded TxnData header.
type TxnDataHeader struct {
GUID string
TripID string
PathHash string
}
var (
errInvalidTxnDataJSON = errors.New("invalid transaction data JSON")
errInvalidTxnDataGUID = errors.New("GUID is not a string")
errInvalidTxnDataTripID = errors.New("trip ID is not a string or null")
errInvalidTxnDataPathHash = errors.New("path hash is not a string or null")
)
// MarshalJSON marshalls a TxnDataHeader as raw JSON.
func (txnData *TxnDataHeader) MarshalJSON() ([]byte, error) {
// Note that, although there are two and four element versions of this header
// in the wild, we will only ever generate the four element version.
buf := bytes.NewBufferString("[")
jsonx.AppendString(buf, txnData.GUID)
// Write the unused second field.
buf.WriteString(",false,")
jsonx.AppendString(buf, txnData.TripID)
buf.WriteString(",")
jsonx.AppendString(buf, txnData.PathHash)
buf.WriteString("]")
return buf.Bytes(), nil
}
// UnmarshalJSON unmarshalls a TxnDataHeader from raw JSON.
func (txnData *TxnDataHeader) UnmarshalJSON(data []byte) error {
var ok bool
var v interface{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
arr, ok := v.([]interface{})
if !ok {
return errInvalidTxnDataJSON
}
if len(arr) < 2 {
return errUnexpectedArraySize{
label: "unexpected number of transaction data elements",
expected: 2,
actual: len(arr),
}
}
if txnData.GUID, ok = arr[0].(string); !ok {
return errInvalidTxnDataGUID
}
// Ignore the unused second field.
// Set up defaults for the optional values.
txnData.TripID = ""
txnData.PathHash = ""
if len(arr) >= 3 {
// Per the cross agent tests, an explicit null is valid here.
if nil != arr[2] {
if txnData.TripID, ok = arr[2].(string); !ok {
return errInvalidTxnDataTripID
}
}
if len(arr) >= 4 {
// Per the cross agent tests, an explicit null is also valid here.
if nil != arr[3] {
if txnData.PathHash, ok = arr[3].(string); !ok {
return errInvalidTxnDataPathHash
}
}
}
}
return nil
}