forked from influxdata/influxdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
notification.go
181 lines (152 loc) · 5.02 KB
/
notification.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
package influxdb
import (
"context"
"encoding/json"
"regexp"
"strings"
)
// NotificationRule is a *Query* of a *Status Bucket* that returns the *Status*.
// When warranted by the rules, sends a *Message* to a 3rd Party
// using the *Notification Endpoint* and stores a receipt in the *Notifications Bucket*.
type NotificationRule interface {
Valid() error
Type() string
json.Marshaler
CRUDLogSetter
SetID(id ID)
SetOrgID(id ID)
SetName(name string)
SetDescription(description string)
GetID() ID
GetCRUDLog() CRUDLog
GetOrgID() ID
GetName() string
GetDescription() string
SetOwnerID(id ID)
ClearPrivateData()
GetOwnerID() ID
SetTaskID(id ID)
GetTaskID() ID
GetEndpointID() ID
GetLimit() *Limit
GenerateFlux(NotificationEndpoint) (string, error)
HasTag(key, value string) bool
}
// NotificationRuleStore represents a service for managing notification rule.
type NotificationRuleStore interface {
// UserResourceMappingService must be part of all NotificationRuleStore service,
// for create, search, delete.
UserResourceMappingService
// OrganizationService is needed for search filter
OrganizationService
// FindNotificationRuleByID returns a single notification rule by ID.
FindNotificationRuleByID(ctx context.Context, id ID) (NotificationRule, error)
// FindNotificationRules returns a list of notification rules that match filter and the total count of matching notification rules.
// Additional options provide pagination & sorting.
FindNotificationRules(ctx context.Context, filter NotificationRuleFilter, opt ...FindOptions) ([]NotificationRule, int, error)
// CreateNotificationRule creates a new notification rule and sets b.ID with the new identifier.
CreateNotificationRule(ctx context.Context, nr NotificationRuleCreate, userID ID) error
// UpdateNotificationRuleUpdateNotificationRule updates a single notification rule.
// Returns the new notification rule after update.
UpdateNotificationRule(ctx context.Context, id ID, nr NotificationRuleCreate, userID ID) (NotificationRule, error)
// PatchNotificationRule updates a single notification rule with changeset.
// Returns the new notification rule state after update.
PatchNotificationRule(ctx context.Context, id ID, upd NotificationRuleUpdate) (NotificationRule, error)
// DeleteNotificationRule removes a notification rule by ID.
DeleteNotificationRule(ctx context.Context, id ID) error
}
// Limit don't notify me more than <limit> times every <limitEvery> seconds.
// If set, limit cannot be empty.
type Limit struct {
Rate int `json:"limit,omitempty"`
// every seconds.
Every int `json:"limitEvery,omitempty"`
}
// NotificationRuleFilter represents a set of filter that restrict the returned notification rules.
type NotificationRuleFilter struct {
OrgID *ID
Organization *string
Tags []Tag
UserResourceMappingFilter
}
// Tag is a tag key-value pair.
type Tag struct {
Key string `json:"key"`
Value string `json:"value"`
}
// NewTag generates a tag pair from a string in the format key:value.
func NewTag(s string) (Tag, error) {
var tagPair Tag
matched, err := regexp.MatchString(`^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+$`, s)
if !matched || err != nil {
return tagPair, &Error{
Code: EInvalid,
Msg: `tag must be in form key:value`,
}
}
slice := strings.Split(s, ":")
tagPair.Key = slice[0]
tagPair.Value = slice[1]
return tagPair, nil
}
// Valid returns an error if the tagpair is missing fields
func (t Tag) Valid() error {
if t.Key == "" || t.Value == "" {
return &Error{
Code: EInvalid,
Msg: "tag must contain a key and a value",
}
}
return nil
}
// QueryParam converts a Tag to a string query parameter
func (t *Tag) QueryParam() string {
return strings.Join([]string{t.Key, t.Value}, ":")
}
// QueryParams Converts NotificationRuleFilter fields to url query params.
func (f NotificationRuleFilter) QueryParams() map[string][]string {
qp := map[string][]string{}
if f.OrgID != nil {
qp["orgID"] = []string{f.OrgID.String()}
}
if f.Organization != nil {
qp["org"] = []string{*f.Organization}
}
qp["tag"] = []string{}
for _, tp := range f.Tags {
qp["tag"] = append(qp["tag"], tp.QueryParam())
}
return qp
}
// NotificationRuleCreate is the struct providing data to create a Notification Rule.
type NotificationRuleCreate struct {
NotificationRule
Status Status `json:"status"`
}
// NotificationRuleUpdate is the set of upgrade fields for patch request.
type NotificationRuleUpdate struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Status *Status `json:"status,omitempty"`
}
// Valid will verify if the NotificationRuleUpdate is valid.
func (n *NotificationRuleUpdate) Valid() error {
if n.Name != nil && *n.Name == "" {
return &Error{
Code: EInvalid,
Msg: "Notification Rule Name can't be empty",
}
}
if n.Description != nil && *n.Description == "" {
return &Error{
Code: EInvalid,
Msg: "Notification Rule Description can't be empty",
}
}
if n.Status != nil {
if err := n.Status.Valid(); err != nil {
return err
}
}
return nil
}