github.com/chenbh/concourse/v6@v6.4.2/atc/event/parser.go (about)

     1  package event
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  	"strings"
     8  
     9  	"github.com/chenbh/concourse/v6/atc"
    10  )
    11  
    12  type eventTable map[atc.EventType]eventVersions
    13  type eventVersions map[atc.EventVersion]eventParser
    14  type eventParser func([]byte) (atc.Event, error)
    15  
    16  var events = eventTable{}
    17  
    18  func unmarshaler(e atc.Event) func([]byte) (atc.Event, error) {
    19  	return func(payload []byte) (atc.Event, error) {
    20  		val := reflect.New(reflect.TypeOf(e))
    21  		err := json.Unmarshal(payload, val.Interface())
    22  		return val.Elem().Interface().(atc.Event), err
    23  	}
    24  }
    25  
    26  func RegisterEvent(e atc.Event) {
    27  	versions, found := events[e.EventType()]
    28  	if !found {
    29  		versions = eventVersions{}
    30  		events[e.EventType()] = versions
    31  	}
    32  
    33  	versions[e.Version()] = unmarshaler(e)
    34  }
    35  
    36  func init() {
    37  	RegisterEvent(InitializeTask{})
    38  	RegisterEvent(StartTask{})
    39  	RegisterEvent(FinishTask{})
    40  	RegisterEvent(InitializeGet{})
    41  	RegisterEvent(StartGet{})
    42  	RegisterEvent(FinishGet{})
    43  	RegisterEvent(InitializePut{})
    44  	RegisterEvent(StartPut{})
    45  	RegisterEvent(FinishPut{})
    46  	RegisterEvent(Status{})
    47  	RegisterEvent(SelectedWorker{})
    48  	RegisterEvent(Log{})
    49  	RegisterEvent(Error{})
    50  
    51  	// deprecated:
    52  	RegisterEvent(InitializeV10{})
    53  	RegisterEvent(FinishV10{})
    54  	RegisterEvent(StartV10{})
    55  	RegisterEvent(InputV10{})
    56  	RegisterEvent(InputV20{})
    57  	RegisterEvent(OutputV10{})
    58  	RegisterEvent(OutputV20{})
    59  	RegisterEvent(ErrorV10{})
    60  	RegisterEvent(ErrorV20{})
    61  	RegisterEvent(ErrorV30{})
    62  	RegisterEvent(FinishTaskV10{})
    63  	RegisterEvent(FinishTaskV20{})
    64  	RegisterEvent(FinishTaskV30{})
    65  	RegisterEvent(InitializeTaskV10{})
    66  	RegisterEvent(InitializeTaskV20{})
    67  	RegisterEvent(InitializeTaskV30{})
    68  	RegisterEvent(StartTaskV10{})
    69  	RegisterEvent(StartTaskV20{})
    70  	RegisterEvent(StartTaskV30{})
    71  	RegisterEvent(StartTaskV40{})
    72  	RegisterEvent(LogV10{})
    73  	RegisterEvent(LogV20{})
    74  	RegisterEvent(LogV30{})
    75  	RegisterEvent(LogV40{})
    76  	RegisterEvent(FinishGetV10{})
    77  	RegisterEvent(FinishGetV20{})
    78  	RegisterEvent(FinishGetV30{})
    79  	RegisterEvent(FinishPutV10{})
    80  	RegisterEvent(FinishPutV20{})
    81  	RegisterEvent(FinishPutV30{})
    82  	RegisterEvent(InitializeGetV10{})
    83  	RegisterEvent(InitializePutV10{})
    84  	RegisterEvent(FinishGetV40{})
    85  	RegisterEvent(FinishPutV40{})
    86  }
    87  
    88  type Message struct {
    89  	Event atc.Event
    90  }
    91  
    92  type Envelope struct {
    93  	Data    *json.RawMessage `json:"data"`
    94  	Event   atc.EventType    `json:"event"`
    95  	Version atc.EventVersion `json:"version"`
    96  }
    97  
    98  func (m Message) MarshalJSON() ([]byte, error) {
    99  	var envelope Envelope
   100  
   101  	payload, err := json.Marshal(m.Event)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	envelope.Data = (*json.RawMessage)(&payload)
   107  	envelope.Event = m.Event.EventType()
   108  	envelope.Version = m.Event.Version()
   109  
   110  	return json.Marshal(envelope)
   111  }
   112  
   113  func (m *Message) UnmarshalJSON(bytes []byte) error {
   114  	var envelope Envelope
   115  
   116  	err := json.Unmarshal(bytes, &envelope)
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	event, err := ParseEvent(envelope.Version, envelope.Event, *envelope.Data)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	m.Event = event
   127  
   128  	return nil
   129  }
   130  
   131  type UnknownEventTypeError struct {
   132  	Type atc.EventType
   133  }
   134  
   135  func (err UnknownEventTypeError) Error() string {
   136  	return fmt.Sprintf("unknown event type: %s", err.Type)
   137  }
   138  
   139  type UnknownEventVersionError struct {
   140  	Type          atc.EventType
   141  	Version       atc.EventVersion
   142  	KnownVersions []string
   143  }
   144  
   145  func (err UnknownEventVersionError) Error() string {
   146  	return fmt.Sprintf(
   147  		"unknown event version: %s version %s (supported versions: %s)",
   148  		err.Type,
   149  		err.Version,
   150  		strings.Join(err.KnownVersions, ", "),
   151  	)
   152  }
   153  
   154  func ParseEvent(version atc.EventVersion, typ atc.EventType, payload []byte) (atc.Event, error) {
   155  	versions, found := events[typ]
   156  	if !found {
   157  		return nil, UnknownEventTypeError{typ}
   158  	}
   159  
   160  	knownVersions := []string{}
   161  	for v, parser := range versions {
   162  		knownVersions = append(knownVersions, string(v))
   163  
   164  		if v.IsCompatibleWith(version) {
   165  			return parser(payload)
   166  		}
   167  	}
   168  
   169  	return nil, UnknownEventVersionError{
   170  		Type:          typ,
   171  		Version:       version,
   172  		KnownVersions: knownVersions,
   173  	}
   174  }