github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/devicetwin/dttype/types.go (about) 1 package dttype 2 3 import ( 4 "encoding/json" 5 "errors" 6 "strings" 7 "time" 8 9 "github.com/satori/go.uuid" 10 11 "github.com/kubeedge/kubeedge/edge/pkg/devicetwin/dtclient" 12 "github.com/kubeedge/kubeedge/edge/pkg/devicetwin/dtcommon" 13 ) 14 15 //Device the struct of device 16 type Device struct { 17 ID string `json:"id,omitempty"` 18 Name string `json:"name,omitempty"` 19 Description string `json:"description,omitempty"` 20 State string `json:"state,omitempty"` 21 LastOnline string `json:"last_online,omitempty"` 22 Attributes map[string]*MsgAttr `json:"attributes,omitempty"` 23 Twin map[string]*MsgTwin `json:"twin,omitempty"` 24 } 25 26 //BaseMessage the base struct of event message 27 type BaseMessage struct { 28 EventID string `json:"event_id"` 29 Timestamp int64 `json:"timestamp"` 30 } 31 32 //SetEventID set event id 33 func (bs *BaseMessage) SetEventID(eventID string) { 34 bs.EventID = eventID 35 } 36 37 //BuildBaseMessage build base msg 38 func BuildBaseMessage() BaseMessage { 39 now := time.Now().UnixNano() / 1e6 40 return BaseMessage{ 41 EventID: uuid.NewV4().String(), 42 Timestamp: now} 43 } 44 45 //Parameter container para 46 type Parameter struct { 47 EventID string 48 Code int 49 Reason string 50 } 51 52 // Result the struct of Result for sending 53 type Result struct { 54 BaseMessage 55 Code int `json:"code,omitempty"` 56 Reason string `json:"reason,omitempty"` 57 } 58 59 //MembershipDetail the struct of membership detail 60 type MembershipDetail struct { 61 BaseMessage 62 Devices []Device `json:"devices"` 63 } 64 65 //MembershipUpdate the struct of membership update 66 type MembershipUpdate struct { 67 BaseMessage 68 AddDevices []Device `json:"added_devices"` 69 RemoveDevices []Device `json:"removed_devices"` 70 } 71 72 //MarshalMembershipUpdate marshal membership update 73 func MarshalMembershipUpdate(result MembershipUpdate) ([]byte, error) { 74 for i := range result.AddDevices { 75 if result.AddDevices[i].Twin != nil { 76 for k, v := range result.AddDevices[i].Twin { 77 if v.Metadata != nil && strings.Compare(v.Metadata.Type, "deleted") == 0 { 78 result.AddDevices[i].Twin[k] = nil 79 } 80 v.ActualVersion = nil 81 v.ExpectedVersion = nil 82 } 83 } 84 } 85 for i := range result.RemoveDevices { 86 if result.RemoveDevices[i].Twin != nil { 87 for k, v := range result.RemoveDevices[i].Twin { 88 if v.Metadata != nil && strings.Compare(v.Metadata.Type, "deleted") == 0 { 89 result.RemoveDevices[i].Twin[k] = nil 90 } 91 v.ActualVersion = nil 92 v.ExpectedVersion = nil 93 } 94 } 95 } 96 resultJSON, err := json.Marshal(result) 97 return resultJSON, err 98 } 99 100 //MsgAttr the struct of device attr 101 type MsgAttr struct { 102 Value string `json:"value"` 103 Optional *bool `json:"optional,omitempty"` 104 Metadata *TypeMetadata `json:"metadata,omitempty"` 105 } 106 107 //MsgTwin the struct of device twin 108 type MsgTwin struct { 109 Expected *TwinValue `json:"expected,omitempty"` 110 Actual *TwinValue `json:"actual,omitempty"` 111 Optional *bool `json:"optional,omitempty"` 112 Metadata *TypeMetadata `json:"metadata,omitempty"` 113 ExpectedVersion *TwinVersion `json:"expected_version,omitempty"` 114 ActualVersion *TwinVersion `json:"actual_version,omitempty"` 115 } 116 117 //TwinValue the struct of twin value 118 type TwinValue struct { 119 Value *string `json:"value,omitempty"` 120 Metadata *ValueMetadata `json:"metadata,omitempty"` 121 } 122 123 //TwinVersion twin version 124 type TwinVersion struct { 125 CloudVersion int64 `json:"cloud"` 126 EdgeVersion int64 `json:"edge"` 127 } 128 129 //TypeMetadata the meta of value type 130 type TypeMetadata struct { 131 Type string `json:"type,omitempty"` 132 } 133 134 //ValueMetadata the meta of value 135 type ValueMetadata struct { 136 Timestamp int64 `json:"timestamp,omitempty"` 137 } 138 139 //UpdateCloudVersion update cloud version 140 func (tv *TwinVersion) UpdateCloudVersion() { 141 tv.CloudVersion = tv.CloudVersion + 1 142 } 143 144 //UpdateEdgeVersion update edge version while dealing edge update 145 func (tv *TwinVersion) UpdateEdgeVersion() { 146 tv.EdgeVersion = tv.EdgeVersion + 1 147 } 148 149 //CompareWithCloud compare with cloud vershon while dealing cloud update req 150 func (tv TwinVersion) CompareWithCloud(tvCloud TwinVersion) bool { 151 return tvCloud.EdgeVersion >= tv.EdgeVersion 152 } 153 154 //UpdateCloudVersion update cloud version 155 func UpdateCloudVersion(version string) (string, error) { 156 var twinversion TwinVersion 157 err := json.Unmarshal([]byte(version), &twinversion) 158 if err != nil { 159 return "", err 160 } 161 twinversion.UpdateCloudVersion() 162 result, err := json.Marshal(twinversion) 163 if err != nil { 164 return "", err 165 } 166 return string(result), nil 167 } 168 169 //UpdateEdgeVersion update Edge version 170 func UpdateEdgeVersion(version string) (string, error) { 171 var twinversion TwinVersion 172 err := json.Unmarshal([]byte(version), &twinversion) 173 if err != nil { 174 return "", err 175 } 176 twinversion.UpdateEdgeVersion() 177 result, err := json.Marshal(twinversion) 178 if err != nil { 179 return "", err 180 } 181 return string(result), nil 182 } 183 184 //CompareVersion compare cloud version 185 func CompareVersion(cloudversion string, edgeversion string) bool { 186 var twincloudversion TwinVersion 187 err := json.Unmarshal([]byte(cloudversion), &twincloudversion) 188 if err != nil { 189 return false 190 } 191 var twinedgeversion TwinVersion 192 err1 := json.Unmarshal([]byte(edgeversion), &twinedgeversion) 193 if err1 != nil { 194 return false 195 } 196 return twinedgeversion.CompareWithCloud(twincloudversion) 197 } 198 199 // ConnectedInfo connected info 200 type ConnectedInfo struct { 201 EventType string `json:"event_type"` 202 TimeStamp int64 `json:"timestamp"` 203 } 204 205 // UnmarshalConnectedInfo unmarshal connected info 206 func UnmarshalConnectedInfo(payload []byte) (ConnectedInfo, error) { 207 var connectedInfo ConnectedInfo 208 err := json.Unmarshal(payload, &connectedInfo) 209 if err != nil { 210 return connectedInfo, err 211 } 212 return connectedInfo, nil 213 } 214 215 //DeviceTwinDocument the struct of twin document 216 type DeviceTwinDocument struct { 217 BaseMessage 218 Twin map[string]*TwinDoc `json:"twin"` 219 } 220 221 //TwinDoc the struct of twin document 222 type TwinDoc struct { 223 LastState *MsgTwin `json:"last"` 224 CurrentState *MsgTwin `json:"current"` 225 } 226 227 //DeviceTwinUpdate the struct of device twin update 228 type DeviceTwinUpdate struct { 229 BaseMessage 230 Twin map[string]*MsgTwin `json:"twin"` 231 } 232 233 // UnmarshalDeviceTwinDocument unmarshal device twin document 234 func UnmarshalDeviceTwinDocument(payload []byte) (*DeviceTwinDocument, error) { 235 var deviceTwinUpdate DeviceTwinDocument 236 err := json.Unmarshal(payload, &deviceTwinUpdate) 237 if err != nil { 238 return &deviceTwinUpdate, err 239 } 240 return &deviceTwinUpdate, nil 241 } 242 243 // UnmarshalDeviceTwinUpdate unmarshal device twin update 244 func UnmarshalDeviceTwinUpdate(payload []byte) (*DeviceTwinUpdate, error) { 245 var deviceTwinUpdate DeviceTwinUpdate 246 err := json.Unmarshal(payload, &deviceTwinUpdate) 247 if err != nil { 248 return &deviceTwinUpdate, errors.New("Unmarshal update request body failed, Please check the request") 249 } 250 if deviceTwinUpdate.Twin == nil { 251 return &deviceTwinUpdate, errors.New("Update twin error, the update request body not have key:twin") 252 } 253 for key, value := range deviceTwinUpdate.Twin { 254 match := dtcommon.ValidateTwinKey(key) 255 errorKey := `The key of twin must be only include upper or lowercase letter, number, english, and special letter - _ . , : / @ # and length of key under 128` 256 if !match { 257 return &deviceTwinUpdate, errors.New(errorKey) 258 } 259 errorValue := `The value of twin must be only include upper or lowercase letter, number, english, and special letter - _ . , : / @ # and length of key under 512` 260 if value != nil { 261 if value.Expected != nil { 262 if value.Expected.Value != nil { 263 if *value.Expected.Value != "" { 264 match := dtcommon.ValidateTwinValue(*value.Expected.Value) 265 if !match { 266 return &deviceTwinUpdate, errors.New(errorValue) 267 } 268 } 269 } 270 } 271 if value.Actual != nil { 272 if value.Actual.Value != nil { 273 if *value.Actual.Value != "" { 274 match := dtcommon.ValidateTwinValue(*value.Actual.Value) 275 if !match { 276 return &deviceTwinUpdate, errors.New(errorValue) 277 } 278 } 279 } 280 } 281 } 282 } 283 return &deviceTwinUpdate, nil 284 } 285 286 //DealTwinResult the result of dealing twin 287 type DealTwinResult struct { 288 Add []dtclient.DeviceTwin 289 Delete []dtclient.DeviceDelete 290 Update []dtclient.DeviceTwinUpdate 291 Result map[string]*MsgTwin 292 SyncResult map[string]*MsgTwin 293 Document map[string]*TwinDoc 294 Err error 295 } 296 297 //DealAttrResult the result of dealing attr 298 type DealAttrResult struct { 299 Add []dtclient.DeviceAttr 300 Delete []dtclient.DeviceDelete 301 Update []dtclient.DeviceAttrUpdate 302 Result map[string]*MsgAttr 303 Err error 304 }