github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/model/event/event.go (about)

     1  package event
     2  
     3  import (
     4  	"encoding/json"
     5  	"time"
     6  
     7  	"github.com/evergreen-ci/evergreen/db/bsonutil"
     8  	"github.com/pkg/errors"
     9  	"gopkg.in/mgo.v2/bson"
    10  )
    11  
    12  const (
    13  	// db constants
    14  	AllLogCollection  = "event_log"
    15  	TaskLogCollection = "task_event_log"
    16  )
    17  
    18  type Event struct {
    19  	Timestamp  time.Time   `bson:"ts" json:"timestamp"`
    20  	ResourceId string      `bson:"r_id" json:"resource_id"`
    21  	EventType  string      `bson:"e_type" json:"event_type"`
    22  	Data       DataWrapper `bson:"data" json:"data"`
    23  }
    24  
    25  var (
    26  	// bson fields for the event struct
    27  	TimestampKey  = bsonutil.MustHaveTag(Event{}, "Timestamp")
    28  	ResourceIdKey = bsonutil.MustHaveTag(Event{}, "ResourceId")
    29  	TypeKey       = bsonutil.MustHaveTag(Event{}, "EventType")
    30  	DataKey       = bsonutil.MustHaveTag(Event{}, "Data")
    31  
    32  	// resource type key.  this doesn't exist a part of the event struct,
    33  	// but has to be the same for all of the event types
    34  	ResourceTypeKey = bsonutil.MustHaveTag(HostEventData{}, "ResourceType")
    35  )
    36  
    37  type DataWrapper struct {
    38  	Data
    39  }
    40  
    41  type Data interface {
    42  	IsValid() bool
    43  }
    44  
    45  // MarshalJSON returns proper JSON encoding by uncovering the Data interface.
    46  func (dw DataWrapper) MarshalJSON() ([]byte, error) {
    47  	switch event := dw.Data.(type) {
    48  	case *TaskEventData:
    49  		return json.Marshal(event)
    50  	case *HostEventData:
    51  		return json.Marshal(event)
    52  	case *SchedulerEventData:
    53  		return json.Marshal(event)
    54  	case *DistroEventData:
    55  		return json.Marshal(event)
    56  	case *TaskSystemResourceData:
    57  		return json.Marshal(event)
    58  	case *TaskProcessResourceData:
    59  		return json.Marshal(event)
    60  	default:
    61  		return nil, errors.Errorf("cannot marshal data of type %T", dw.Data)
    62  	}
    63  }
    64  
    65  func (dw DataWrapper) GetBSON() (interface{}, error) {
    66  	return dw.Data, nil
    67  }
    68  
    69  func (dw *DataWrapper) SetBSON(raw bson.Raw) error {
    70  	impls := []interface{}{&TaskEventData{}, &HostEventData{}, &DistroEventData{}, &SchedulerEventData{},
    71  		&TaskSystemResourceData{}, &TaskProcessResourceData{}}
    72  
    73  	for _, impl := range impls {
    74  		err := raw.Unmarshal(impl)
    75  		if err != nil {
    76  			return err
    77  		}
    78  		if impl.(Data).IsValid() {
    79  			dw.Data = impl.(Data)
    80  			return nil
    81  		}
    82  	}
    83  	m := bson.M{}
    84  	err := raw.Unmarshal(m)
    85  	if err != nil {
    86  		return err
    87  	}
    88  	return errors.Errorf("No suitable type for %#v", m)
    89  }