| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 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
- }
|