github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/event/parser.go (about)

     1  package event
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  	"strings"
     8  
     9  	"github.com/pf-qiu/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(SetPipelineChanged{})
    47  	RegisterEvent(Status{})
    48  	RegisterEvent(SelectedWorker{})
    49  	RegisterEvent(Log{})
    50  	RegisterEvent(Error{})
    51  	RegisterEvent(ImageCheck{})
    52  	RegisterEvent(ImageGet{})
    53  
    54  	// deprecated:
    55  	RegisterEvent(InitializeV10{})
    56  	RegisterEvent(FinishV10{})
    57  	RegisterEvent(StartV10{})
    58  	RegisterEvent(InputV10{})
    59  	RegisterEvent(InputV20{})
    60  	RegisterEvent(OutputV10{})
    61  	RegisterEvent(OutputV20{})
    62  	RegisterEvent(ErrorV10{})
    63  	RegisterEvent(ErrorV20{})
    64  	RegisterEvent(ErrorV30{})
    65  	RegisterEvent(FinishTaskV10{})
    66  	RegisterEvent(FinishTaskV20{})
    67  	RegisterEvent(FinishTaskV30{})
    68  	RegisterEvent(InitializeTaskV10{})
    69  	RegisterEvent(InitializeTaskV20{})
    70  	RegisterEvent(InitializeTaskV30{})
    71  	RegisterEvent(StartTaskV10{})
    72  	RegisterEvent(StartTaskV20{})
    73  	RegisterEvent(StartTaskV30{})
    74  	RegisterEvent(StartTaskV40{})
    75  	RegisterEvent(LogV10{})
    76  	RegisterEvent(LogV20{})
    77  	RegisterEvent(LogV30{})
    78  	RegisterEvent(LogV40{})
    79  	RegisterEvent(FinishGetV10{})
    80  	RegisterEvent(FinishGetV20{})
    81  	RegisterEvent(FinishGetV30{})
    82  	RegisterEvent(FinishPutV10{})
    83  	RegisterEvent(FinishPutV20{})
    84  	RegisterEvent(FinishPutV30{})
    85  	RegisterEvent(InitializeGetV10{})
    86  	RegisterEvent(InitializePutV10{})
    87  	RegisterEvent(FinishGetV40{})
    88  	RegisterEvent(FinishPutV40{})
    89  }
    90  
    91  type Message struct {
    92  	Event atc.Event
    93  }
    94  
    95  type Envelope struct {
    96  	Data    *json.RawMessage `json:"data"`
    97  	Event   atc.EventType    `json:"event"`
    98  	Version atc.EventVersion `json:"version"`
    99  }
   100  
   101  func (m Message) MarshalJSON() ([]byte, error) {
   102  	var envelope Envelope
   103  
   104  	payload, err := json.Marshal(m.Event)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  
   109  	envelope.Data = (*json.RawMessage)(&payload)
   110  	envelope.Event = m.Event.EventType()
   111  	envelope.Version = m.Event.Version()
   112  
   113  	return json.Marshal(envelope)
   114  }
   115  
   116  func (m *Message) UnmarshalJSON(bytes []byte) error {
   117  	var envelope Envelope
   118  
   119  	err := json.Unmarshal(bytes, &envelope)
   120  	if err != nil {
   121  		return err
   122  	}
   123  
   124  	event, err := ParseEvent(envelope.Version, envelope.Event, *envelope.Data)
   125  	if err != nil {
   126  		return err
   127  	}
   128  
   129  	m.Event = event
   130  
   131  	return nil
   132  }
   133  
   134  type UnknownEventTypeError struct {
   135  	Type atc.EventType
   136  }
   137  
   138  func (err UnknownEventTypeError) Error() string {
   139  	return fmt.Sprintf("unknown event type: %s", err.Type)
   140  }
   141  
   142  type UnknownEventVersionError struct {
   143  	Type          atc.EventType
   144  	Version       atc.EventVersion
   145  	KnownVersions []string
   146  }
   147  
   148  func (err UnknownEventVersionError) Error() string {
   149  	return fmt.Sprintf(
   150  		"unknown event version: %s version %s (supported versions: %s)",
   151  		err.Type,
   152  		err.Version,
   153  		strings.Join(err.KnownVersions, ", "),
   154  	)
   155  }
   156  
   157  func ParseEvent(version atc.EventVersion, typ atc.EventType, payload []byte) (atc.Event, error) {
   158  	versions, found := events[typ]
   159  	if !found {
   160  		return nil, UnknownEventTypeError{typ}
   161  	}
   162  
   163  	knownVersions := []string{}
   164  	for v, parser := range versions {
   165  		knownVersions = append(knownVersions, string(v))
   166  
   167  		if v.IsCompatibleWith(version) {
   168  			return parser(payload)
   169  		}
   170  	}
   171  
   172  	return nil, UnknownEventVersionError{
   173  		Type:          typ,
   174  		Version:       version,
   175  		KnownVersions: knownVersions,
   176  	}
   177  }