-
Notifications
You must be signed in to change notification settings - Fork 1
/
events.go
188 lines (166 loc) · 5.64 KB
/
events.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package kizcool
import (
"encoding/json"
"fmt"
log "github.com/sirupsen/logrus"
)
// Event is an interface for any event
type Event interface {
Kind() string
}
// GenericEvent is the minimal set of fields shared by all events
type GenericEvent struct {
Timestamp int `json:"timestamp,omitempty"`
Name string `json:"name,omitempty"`
}
// Kind returns a partial text description of the event
func (e *GenericEvent) Kind() string {
return fmt.Sprintf("%v", e)
}
// ExecutionEvent is the minimal set of fields shared by all Execution events
type ExecutionEvent struct {
ExecID ExecID `json:"execID,omitempty"`
SetupOID string `json:"setupOID,omitempty"`
SubType int `json:"subType,omitempty"`
Type int `json:"type,omitempty"`
}
// ExecutionRegisteredEvent indicates an execution has been registered
type ExecutionRegisteredEvent struct {
GenericEvent
ExecutionEvent
Label string `json:"label,omitempty"`
Metadata string `json:"metadata,omitempty"`
TriggerID string `json:"triggerId,omitempty"`
Actions []Action `json:"actions,omitempty"`
}
// ExecutionStateChangedEvent indicates a change in the state of an execution
type ExecutionStateChangedEvent struct {
GenericEvent
ExecutionEvent
NewState string `json:"newState,omitempty"`
OldState string `json:"oldState,omitempty"`
OwnerKey string `json:"ownerKey,omitempty"`
TimeToNextState int `json:"timeToNextState,omitempty"`
}
// CommandExecutionStateChangedEvent indicates a change in the state of the execution of a command
type CommandExecutionStateChangedEvent struct {
GenericEvent
DeviceURL DeviceURL `json:"deviceURL,omitempty"`
ExecID ExecID `json:"execID,omitempty"`
SetupOID string `json:"setupOID,omitempty"`
NewState string `json:"newState,omitempty"`
FailureType string `json:"failureType,omitempty"`
FailureTypeCode int `json:"failureTypeCode,omitempty"`
Rank int `json:"rank,omitempty"`
}
// GatewayEvent indicates an event related to a gateway
type GatewayEvent struct {
GatewayID string `json:"gatewayId,omitempty"`
}
// GatewaySynchronizationStartedEvent indicates the start of synchronization of a gateway
type GatewaySynchronizationStartedEvent struct {
GenericEvent
GatewayEvent
}
// GatewaySynchronizationEndedEvent indicates the end of synchronization of a gateway
type GatewaySynchronizationEndedEvent struct {
GenericEvent
GatewayEvent
}
// GatewayDownEvent indicates the gateway has become unreachable
type GatewayDownEvent struct {
GenericEvent
GatewayEvent
}
// GatewayAliveEvent indicates the gateway is accessible again
type GatewayAliveEvent struct {
GenericEvent
GatewayEvent
}
// RefreshAllDevicesStatesCompletedEvent indicates the end of a request to get the state of all devices
type RefreshAllDevicesStatesCompletedEvent struct {
GenericEvent
GatewayEvent
ProtocolType int `json:"protocolType,omitempty"`
}
// DeviceStateChangedEvent indicates a change in the state of a device
type DeviceStateChangedEvent struct {
GenericEvent
SetupOID string `json:"setupOID,omitempty"`
DeviceURL DeviceURL `json:"deviceURL,omitempty"`
DeviceStates []DeviceState `json:"deviceStates,omitempty"`
}
// EndUserLoginEvent happens when a user authenticates
type EndUserLoginEvent struct {
GenericEvent
SetupOID string `json:"setupOID,omitempty"`
UserID string `json:"userId,omitempty"`
UserAgentType string `json:"userAgentType,omitempty"`
}
// Events is a slide of Event, used for unmarshalling several events of unknown type from json
type Events []Event
// UnmarshalJSON unmarshals an event from json, detecting the right event type
func (events *Events) UnmarshalJSON(data []byte) error {
// this just splits up the JSON array into the raw JSON for each object
var raw []json.RawMessage
err := json.Unmarshal(data, &raw)
if err != nil {
log.WithFields(log.Fields{
"data": data,
"err": err,
}).Debug("Error splitting into raw items")
return fmt.Errorf("Error splitting json into raw items. %w", err)
}
for _, r := range raw {
// unamrshal into a map to check the "Name" field
var obj map[string]interface{}
err := json.Unmarshal(r, &obj)
if err != nil {
log.WithFields(log.Fields{
"err": err,
"data": r,
}).Debug("Error retrieving Name field")
return fmt.Errorf("Error retrieving Name field. %w", err)
}
eventType := ""
if t, ok := obj["name"].(string); ok {
eventType = t
}
// unmarshal again into the correct type
var actual Event
switch eventType {
case "ExecutionRegisteredEvent":
actual = &ExecutionRegisteredEvent{}
case "ExecutionStateChangedEvent":
actual = &ExecutionStateChangedEvent{}
case "CommandExecutionStateChangedEvent":
actual = &CommandExecutionStateChangedEvent{}
case "GatewaySynchronizationStartedEvent":
actual = &GatewaySynchronizationStartedEvent{}
case "GatewaySynchronizationEndedEvent":
actual = &GatewaySynchronizationEndedEvent{}
case "GatewayDownEvent":
actual = &GatewayDownEvent{}
case "GatewayAliveEvent":
actual = &GatewayAliveEvent{}
case "RefreshAllDevicesStatesCompletedEvent":
actual = &RefreshAllDevicesStatesCompletedEvent{}
case "DeviceStateChangedEvent":
actual = &DeviceStateChangedEvent{}
case "EndUserLoginEvent":
actual = &EndUserLoginEvent{}
default:
return fmt.Errorf("Cannot unmarshal unknown event of type %s: %v", eventType, obj)
}
err = json.Unmarshal(r, actual)
if err != nil {
log.WithFields(log.Fields{
"err": err,
"data": r,
}).Debug("Error unmarshalling into struct")
return fmt.Errorf("Error unmarshalling into struct. %w", err)
}
*events = append(*events, actual)
}
return nil
}