| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package protoutil |
| 6 |
| 7 import ( |
| 8 "errors" |
| 9 "fmt" |
| 10 "time" |
| 11 |
| 12 "github.com/luci/luci-go/common/logdog/protocol" |
| 13 "github.com/luci/luci-go/common/logdog/types" |
| 14 ) |
| 15 |
| 16 const ( |
| 17 nanosecondsInASecond = int64(time.Second / time.Nanosecond) |
| 18 ) |
| 19 |
| 20 // DescriptorPath returns the StreamPath for a descriptor. |
| 21 func DescriptorPath(d *protocol.LogStreamDescriptor) types.StreamPath { |
| 22 if d == nil { |
| 23 return types.StreamPath("") |
| 24 } |
| 25 return types.StreamName(d.GetPrefix()).Join(types.StreamName(d.GetName()
)) |
| 26 } |
| 27 |
| 28 // NewTimestamp creates a new Butler protocol Timestamp from a time.Time type. |
| 29 func NewTimestamp(t time.Time) *protocol.Timestamp { |
| 30 val := t.UTC().Format(time.RFC3339Nano) |
| 31 return &protocol.Timestamp{ |
| 32 Value: &val, |
| 33 } |
| 34 } |
| 35 |
| 36 // GetTimestampTime returns the time.Time associated with the Timestamp. |
| 37 func GetTimestampTime(ts *protocol.Timestamp) (time.Time, error) { |
| 38 t, err := time.Parse(time.RFC3339Nano, ts.GetValue()) |
| 39 if err != nil { |
| 40 return time.Time{}, fmt.Errorf("failed to parse timestamp from [
%s]: %s", ts.GetValue(), err) |
| 41 } |
| 42 return t.UTC(), nil |
| 43 } |
| 44 |
| 45 // NewTimeOffset returns the equivalent time offset in microseconds for a |
| 46 // time.Duration. |
| 47 func NewTimeOffset(d time.Duration) *protocol.TimeOffset { |
| 48 nano := d.Nanoseconds() |
| 49 if nano < 0 { |
| 50 nano = 0 |
| 51 } |
| 52 seconds := nano / nanosecondsInASecond |
| 53 nanoseconds := nano - (seconds * nanosecondsInASecond) |
| 54 |
| 55 to := protocol.TimeOffset{} |
| 56 if seconds != 0 { |
| 57 u32Seconds := uint32(seconds) |
| 58 to.Seconds = &u32Seconds |
| 59 } |
| 60 if nanoseconds != 0 { |
| 61 u32Nanoseconds := uint32(nanoseconds) |
| 62 to.Nanoseconds = &u32Nanoseconds |
| 63 } |
| 64 return &to |
| 65 } |
| 66 |
| 67 // TimeOffset converts a TimeOffset protocol buffer to a time.Duration. |
| 68 func TimeOffset(o *protocol.TimeOffset) time.Duration { |
| 69 return (time.Duration(o.GetSeconds()) * time.Second) + (time.Duration(o.
GetNanoseconds()) * time.Nanosecond) |
| 70 } |
| 71 |
| 72 // ValidateDescriptor returns an error if the supplied LogStreamDescriptor is |
| 73 // not complete and valid. |
| 74 func ValidateDescriptor(d *protocol.LogStreamDescriptor) error { |
| 75 if err := types.StreamName(d.GetPrefix()).Validate(); err != nil { |
| 76 return fmt.Errorf("invalid prefix: %s", err) |
| 77 } |
| 78 if err := types.StreamName(d.GetName()).Validate(); err != nil { |
| 79 return fmt.Errorf("invalid name: %s", err) |
| 80 } |
| 81 |
| 82 timestamp := d.GetTimestamp() |
| 83 if timestamp == nil { |
| 84 return errors.New("missing timestamp") |
| 85 } |
| 86 if _, err := GetTimestampTime(timestamp); err != nil { |
| 87 return fmt.Errorf("invalid timestamp value [%s]: %s", timestamp.
GetValue(), err) |
| 88 } |
| 89 for i, tag := range d.GetTags() { |
| 90 t := types.StreamTag{ |
| 91 Key: tag.GetKey(), |
| 92 Value: tag.GetValue(), |
| 93 } |
| 94 if err := t.Validate(); err != nil { |
| 95 return fmt.Errorf("invalid tag #%d: %s", i, err) |
| 96 } |
| 97 } |
| 98 return nil |
| 99 } |
| 100 |
| 101 // ValidateLogEntry returns an error if the supplied LogEntry is not complete |
| 102 // and valid. |
| 103 func ValidateLogEntry(e *protocol.LogEntry) error { |
| 104 hasContent := len(e.GetLines()) > 0 |
| 105 if !hasContent { |
| 106 for _, d := range e.GetData() { |
| 107 if len(d.Value) > 0 { |
| 108 hasContent = true |
| 109 break |
| 110 } |
| 111 } |
| 112 } |
| 113 if !hasContent { |
| 114 return errors.New("no content") |
| 115 } |
| 116 return nil |
| 117 } |
| OLD | NEW |