-
Notifications
You must be signed in to change notification settings - Fork 466
/
envelope.go
121 lines (111 loc) · 3.61 KB
/
envelope.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
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
package pubsub
import (
"github.com/google/uuid"
jsoniter "github.com/json-iterator/go"
)
const (
// DefaultCloudEventType is the default event type for an Dapr published event
DefaultCloudEventType = "com.dapr.event.sent"
// CloudEventsSpecVersion is the specversion used by Dapr for the cloud events implementation
CloudEventsSpecVersion = "1.0"
// ContentType is the Cloud Events HTTP content type
ContentType = "application/cloudevents+json"
// DefaultCloudEventSource is the default event source
DefaultCloudEventSource = "Dapr"
// DefaultCloudEventDataContentType is the default content-type for the data attribute
DefaultCloudEventDataContentType = "text/plain"
)
// CloudEventsEnvelope describes the Dapr implementation of the Cloud Events spec
// Spec details: https://github.com/cloudevents/spec/blob/master/spec.md
type CloudEventsEnvelope struct {
ID string `json:"id"`
Source string `json:"source"`
Type string `json:"type"`
SpecVersion string `json:"specversion"`
DataContentType string `json:"datacontenttype"`
Data interface{} `json:"data"`
Subject string `json:"subject"`
Topic string `json:"topic"`
PubsubName string `json:"pubsubname"`
}
// NewCloudEventsEnvelope returns CloudEventsEnvelope from data or a new one when data content was not
func NewCloudEventsEnvelope(id, source, eventType, subject string, topic string, pubsubName string, dataContentType string, data []byte) *CloudEventsEnvelope {
// defaults
if id == "" {
id = uuid.New().String()
}
if source == "" {
source = DefaultCloudEventSource
}
if eventType == "" {
eventType = DefaultCloudEventType
}
if subject == "" {
subject = DefaultCloudEventSource
}
if dataContentType == "" {
dataContentType = DefaultCloudEventDataContentType
}
// check if JSON
var j interface{}
err := jsoniter.Unmarshal(data, &j)
if err != nil {
// not JSON, return new envelope
return &CloudEventsEnvelope{
ID: id,
SpecVersion: CloudEventsSpecVersion,
DataContentType: dataContentType,
Source: source,
Type: eventType,
Subject: subject,
Topic: topic,
PubsubName: pubsubName,
Data: string(data),
}
}
// handle CloudEvent
m, isMap := j.(map[string]interface{})
if isMap {
if _, isCE := m["specversion"]; isCE {
ce := &CloudEventsEnvelope{
ID: getStrVal(m, "id"),
SpecVersion: getStrVal(m, "specversion"),
DataContentType: getStrVal(m, "datacontenttype"),
Source: getStrVal(m, "source"),
Type: getStrVal(m, "type"),
Subject: getStrVal(m, "subject"),
Topic: topic,
PubsubName: pubsubName,
Data: m["data"],
}
// check if CE is valid
if ce.ID != "" && ce.SpecVersion != "" && ce.DataContentType != "" {
return ce
}
}
}
// content was JSON but not a valid CloudEvent, make one
return &CloudEventsEnvelope{
ID: id,
SpecVersion: CloudEventsSpecVersion,
DataContentType: "application/json",
Source: source,
Type: eventType,
Subject: subject,
Topic: topic,
PubsubName: pubsubName,
Data: j,
}
}
func getStrVal(m map[string]interface{}, key string) string {
if v, k := m[key]; k {
if s, ok := v.(string); ok {
return s
}
}
return ""
}